* logic added in mbed_overrides.c - for making system initialization (system_init) before usart init. Had issues for clock and buses not getting initialed before serial init. Resolved with the logic.

* Macro for callback added in usart.h (ASF).
* GPIO mode setting implemented in gpio_api.c
* updated files gpio_object.h ,serial_api.h(tested and working for UART synchronous APIs)
* Reverted settings.py
* Removed unused files in usart (ASF).
pull/1214/head
akhilpanayamparambil 2015-06-16 18:41:13 +05:30 committed by Karthik Purushothaman
parent d6109db325
commit cfffe1371d
10 changed files with 554 additions and 737 deletions

View File

@ -15,14 +15,19 @@
*/ */
#include "mbed_assert.h" #include "mbed_assert.h"
#include "compiler.h" #include "compiler.h"
#include "system.h" #include "system.h"
uint8_t g_sys_init = 0;
//called before main - implement here if board needs it ortherwise, let //called before main - implement here if board needs it ortherwise, let
// the application override this if necessary // the application override this if necessary
//TODO: To be implemented by adding system init and board init //TODO: To be implemented by adding system init and board init
void mbed_sdk_init() void mbed_sdk_init()
{ {
system_init(); if(g_sys_init == 0)
{
g_sys_init = 1;
system_init();
}
} }
/***************************************************************/ /***************************************************************/

View File

@ -1,116 +0,0 @@
/**
* \file
*
* \brief SAM USART Quick Start
*
* Copyright (C) 2012-2014 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/**
* \page asfdoc_sam0_sercom_usart_basic_use_case Quick Start Guide for SERCOM USART - Basic
*
* This quick start will echo back characters typed into the terminal. In this
* use case the USART will be configured with the following settings:
* - Asynchronous mode
* - 9600 Baudrate
* - 8-bits, No Parity and one Stop Bit
* - TX and RX enabled and connected to the Xplained Pro Embedded Debugger virtual COM port
*
* \section asfdoc_sam0_sercom_usart_basic_use_case_setup Setup
*
* \subsection asfdoc_sam0_sercom_usart_basic_use_case_prereq Prerequisites
* There are no special setup requirements for this use-case.
*
* \subsection asfdoc_sam0_usart_basic_use_case_setup_code Code
* Add to the main application source file, outside of any functions:
* \snippet qs_usart_basic_use.c module_inst
*
* Copy-paste the following setup code to your user application:
* \snippet qs_usart_basic_use.c setup
*
* Add to user application initialization (typically the start of \c main()):
* \snippet qs_usart_basic_use.c setup_init
*
* \subsection asfdoc_sam0_usart_basic_use_case_setup_flow Workflow
* -# Create a module software instance structure for the USART module to store
* the USART driver state while it is in use.
* \snippet qs_usart_basic_use.c module_inst
* \note This should never go out of scope as long as the module is in use.
* In most cases, this should be global.
*
* -# Configure the USART module.
* -# Create a USART module configuration struct, which can be filled out to
* adjust the configuration of a physical USART peripheral.
* \snippet qs_usart_basic_use.c setup_config
* -# Initialize the USART configuration struct with the module's default values.
* \snippet qs_usart_basic_use.c setup_config_defaults
* \note This should always be performed before using the configuration
* struct to ensure that all values are initialized to known default
* settings.
*
* -# Alter the USART settings to configure the physical pinout, baudrate, and
* other relevant parameters.
* \snippet qs_usart_basic_use.c setup_change_config
* -# Configure the USART module with the desired settings, retrying while the
* driver is busy until the configuration is stressfully set.
* \snippet qs_usart_basic_use.c setup_set_config
* -# Enable the USART module.
* \snippet qs_usart_basic_use.c setup_enable
*
*
* \section asfdoc_sam0_usart_basic_use_case_main Use Case
*
* \subsection asfdoc_sam0_usart_basic_use_case_main_code Code
* Copy-paste the following code to your user application:
* \snippet qs_usart_basic_use.c main
*
* \subsection asfdoc_sam0_usart_basic_use_case_main_flow Workflow
* -# Send a string to the USART to show the demo is running, blocking until
* all characters have been sent.
* \snippet qs_usart_basic_use.c main_send_string
* -# Enter an infinite loop to continuously echo received values on the USART.
* \snippet qs_usart_basic_use.c main_loop
* -# Perform a blocking read of the USART, storing the received character into
* the previously declared temporary variable.
* \snippet qs_usart_basic_use.c main_read
* -# Echo the received variable back to the USART via a blocking write.
* \snippet qs_usart_basic_use.c main_write
*/
/**
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/

View File

@ -1,130 +0,0 @@
/**
* \file
*
* \brief SAM USART Quick Start
*
* Copyright (C) 2012-2014 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/**
* \page asfdoc_sam0_sercom_usart_callback_use_case Quick Start Guide for SERCOM USART - Callback
*
* This quick start will echo back characters typed into the terminal, using
* asynchronous TX and RX callbacks from the USART peripheral. In this use case
* the USART will be configured with the following settings:
* - Asynchronous mode
* - 9600 Baudrate
* - 8-bits, No Parity and one Stop Bit
* - TX and RX enabled and connected to the Xplained Pro Embedded Debugger virtual COM port
*
* \section asfdoc_sam0_sercom_usart_callback_use_case_setup Setup
*
* \subsection asfdoc_sam0_sercom_usart_callback_use_case_prereq Prerequisites
* There are no special setup requirements for this use-case.
*
* \subsection asfdoc_sam0_usart_callback_use_case_setup_code Code
* Add to the main application source file, outside of any functions:
* \snippet qs_usart_callback.c module_inst
* \snippet qs_usart_callback.c rx_buffer_var
*
* Copy-paste the following callback function code to your user application:
* \snippet qs_usart_callback.c callback_funcs
*
* Copy-paste the following setup code to your user application:
* \snippet qs_usart_callback.c setup
*
* Add to user application initialization (typically the start of \c main()):
* \snippet qs_usart_callback.c setup_init
*
* \subsection asfdoc_sam0_usart_callback_use_case_setup_flow Workflow
* -# Create a module software instance structure for the USART module to store
* the USART driver state while it is in use.
* \snippet qs_usart_callback.c module_inst
* \note This should never go out of scope as long as the module is in use.
* In most cases, this should be global.
*
* -# Configure the USART module.
* -# Create a USART module configuration struct, which can be filled out to
* adjust the configuration of a physical USART peripheral.
* \snippet qs_usart_callback.c setup_config
* -# Initialize the USART configuration struct with the module's default values.
* \snippet qs_usart_callback.c setup_config_defaults
* \note This should always be performed before using the configuration
* struct to ensure that all values are initialized to known default
* settings.
*
* -# Alter the USART settings to configure the physical pinout, baudrate, and
* other relevant parameters.
* \snippet qs_usart_callback.c setup_change_config
* -# Configure the USART module with the desired settings, retrying while the
* driver is busy until the configuration is stressfully set.
* \snippet qs_usart_callback.c setup_set_config
* -# Enable the USART module.
* \snippet qs_usart_callback.c setup_enable
* -# Configure the USART callbacks.
* -# Register the TX and RX callback functions with the driver.
* \snippet qs_usart_callback.c setup_register_callbacks
* -# Enable the TX and RX callbacks so that they will be called by the driver
* when appropriate.
* \snippet qs_usart_callback.c setup_enable_callbacks
*
* \section asfdoc_sam0_usart_callback_use_case_main Use Case
*
* \subsection asfdoc_sam0_usart_callback_use_case_main_code Code
* Copy-paste the following code to your user application:
* \snippet qs_usart_callback.c main
*
* \subsection asfdoc_sam0_usart_callback_use_case_main_flow Workflow
* -# Enable global interrupts, so that the callbacks can be fired.
* \snippet qs_usart_callback.c enable_global_interrupts
* -# Send a string to the USART to show the demo is running, blocking until
* all characters have been sent.
* \snippet qs_usart_callback.c main_send_string
* -# Enter an infinite loop to continuously echo received values on the USART.
* \snippet qs_usart_callback.c main_loop
* -# Perform an asynchronous read of the USART, which will fire the registered
* callback when characters are received.
* \snippet qs_usart_callback.c main_read
*/
/**
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <asf.h>
#include <conf_clocks.h>

View File

@ -1,214 +0,0 @@
/**
* \file
*
* \brief SAM D21/R21/D10/D11 Quick Start Guide for Using Usart driver with DMA
*
* Copyright (C) 2014 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/**
* \page asfdoc_sam0_sercom_usart_dma_use_case Quick Start Guide for Using DMA with SERCOM USART
*
* The supported board list:
* - SAML21 Xplained Pro
* - SAMD21 Xplained Pro
* - SAMR21 Xplained Pro
* - SAMD11 Xplained Pro
*
* This quick start will receiving eight bytes of data from PC terminal and transmit back the string
* to the terminal through DMA. In this use case the USART will be configured with the following
* settings:
* - Asynchronous mode
* - 9600 Baudrate
* - 8-bits, No Parity and one Stop Bit
* - TX and RX enabled and connected to the Xplained Pro Embedded Debugger virtual COM port
*
* \section asfdoc_sam0_sercom_usart_dma_use_case_setup Setup
*
* \subsection asfdoc_sam0_sercom_usart_dma_use_case_prereq Prerequisites
* There are no special setup requirements for this use-case.
*
* \subsection asfdoc_sam0_usart_dma_use_case_setup_code Code
* Add to the main application source file, outside of any functions:
* \snippet qs_usart_dma_use.c module_inst
* \snippet qs_usart_dma_use.c dma_resource
* \snippet qs_usart_dma_use.c usart_buffer
* \snippet qs_usart_dma_use.c transfer_descriptor
*
* Copy-paste the following setup code to your user application:
* \snippet qs_usart_dma_use.c setup
*
* Add to user application initialization (typically the start of \c main()):
* \snippet qs_usart_dma_use.c setup_init
*
* \subsection asfdoc_sam0_usart_dma_use_case_setup_flow Workflow
*
* \subsubsection asfdoc_sam0_usart_dma_use_case_setup_flow_inst Create variables
* -# Create a module software instance structure for the USART module to store
* the USART driver state while it is in use.
* \snippet qs_usart_dma_use.c module_inst
* \note This should never go out of scope as long as the module is in use.
* In most cases, this should be global.
*
* -# Create module software instance structures for DMA resources to store
* the DMA resource state while it is in use.
* \snippet qs_usart_dma_use.c dma_resource
* \note This should never go out of scope as long as the module is in use.
* In most cases, this should be global.
*
* -# Create a buffer to store the data to be transferred /received.
* \snippet qs_usart_dma_use.c usart_buffer
* -# Create DMA transfer descriptors for RX/TX.
* \snippet qs_usart_dma_use.c transfer_descriptor
*
* \subsubsection asfdoc_sam0_usart_dma_use_case_setup_flow_usart Configure the USART
* -# Create a USART module configuration struct, which can be filled out to
* adjust the configuration of a physical USART peripheral.
* \snippet qs_usart_dma_use.c setup_config
* -# Initialize the USART configuration struct with the module's default values.
* \snippet qs_usart_dma_use.c setup_config_defaults
* \note This should always be performed before using the configuration
* struct to ensure that all values are initialized to known default
* settings.
*
* -# Alter the USART settings to configure the physical pinout, baudrate, and
* other relevant parameters.
* \snippet qs_usart_dma_use.c setup_change_config
* -# Configure the USART module with the desired settings, retrying while the
* driver is busy until the configuration is stressfully set.
* \snippet qs_usart_dma_use.c setup_set_config
* -# Enable the USART module.
* \snippet qs_usart_dma_use.c setup_enable
*
* \subsubsection asfdoc_sam0_usart_dma_use_case_setup_flow_dma Configure DMA
* -# Create a callback function of receiver done.
* \snippet qs_usart_dma_use.c transfer_done_rx
*
* -# Create a callback function of transmission done.
* \snippet qs_usart_dma_use.c transfer_done_tx
*
* -# Create a DMA resource configuration structure, which can be filled out to
* adjust the configuration of a single DMA transfer.
* \snippet qs_usart_dma_use.c setup_rx_1
*
* -# Initialize the DMA resource configuration struct with the module's
* default values.
* \snippet qs_usart_dma_use.c setup_rx_2
* \note This should always be performed before using the configuration
* struct to ensure that all values are initialized to known default
* settings.
*
* -# Set extra configurations for the DMA resource. It is using peripheral
* trigger. SERCOM TX empty trigger causes a beat transfer in
* this example.
* \snippet qs_usart_dma_use.c setup_rx_3
*
* -# Allocate a DMA resource with the configurations.
* \snippet qs_usart_dma_use.c setup_rx_4
*
* -# Create a DMA transfer descriptor configuration structure, which can be
* filled out to adjust the configuration of a single DMA transfer.
* \snippet qs_usart_dma_use.c setup_rx_5
*
* -# Initialize the DMA transfer descriptor configuration struct with the module's
* default values.
* \snippet qs_usart_dma_use.c setup_rx_6
* \note This should always be performed before using the configuration
* struct to ensure that all values are initialized to known default
* settings.
*
* -# Set the specific parameters for a DMA transfer with transfer size, source
* address, and destination address.
* \snippet qs_usart_dma_use.c setup_rx_7
*
* -# Create the DMA transfer descriptor.
* \snippet qs_usart_dma_use.c setup_rx_8
*
* -# Create a DMA resource configuration structure for TX, which can be filled
* out to adjust the configuration of a single DMA transfer.
* \snippet qs_usart_dma_use.c setup_tx_1
*
* -# Initialize the DMA resource configuration struct with the module's
* default values.
* \snippet qs_usart_dma_use.c setup_tx_2
* \note This should always be performed before using the configuration
* struct to ensure that all values are initialized to known default
* settings.
*
* -# Set extra configurations for the DMA resource. It is using peripheral
* trigger. SERCOM RX Ready trigger causes a beat transfer in
* this example.
* \snippet qs_usart_dma_use.c setup_tx_3
*
* -# Allocate a DMA resource with the configurations.
* \snippet qs_usart_dma_use.c setup_tx_4
*
* -# Create a DMA transfer descriptor configuration structure, which can be
* filled out to adjust the configuration of a single DMA transfer.
* \snippet qs_usart_dma_use.c setup_tx_5
*
* -# Initialize the DMA transfer descriptor configuration struct with the module's
* default values.
* \snippet qs_usart_dma_use.c setup_tx_6
* \note This should always be performed before using the configuration
* struct to ensure that all values are initialized to known default
* settings.
*
* -# Set the specific parameters for a DMA transfer with transfer size, source
* address, and destination address.
* \snippet qs_usart_dma_use.c setup_tx_7
*
* -# Create the DMA transfer descriptor.
* \snippet qs_usart_dma_use.c setup_tx_8
*
* \section asfdoc_sam0_usart_dma_use_case_main Use Case
*
* \subsection asfdoc_sam0_usart_dma_use_case_main_code Code
* Copy-paste the following code to your user application:
* \snippet qs_usart_dma_use.c main
*
* \subsection asfdoc_sam0_usart_dma_use_case_main_flow Workflow
* -# Wait for receiving data.
* \snippet qs_usart_dma_use.c main_1
*
* -# Enter endless loop.
* \snippet qs_usart_dma_use.c endless_loop
*/
/**
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/

View File

@ -256,6 +256,8 @@
#include <sercom.h> #include <sercom.h>
#include <pinmux.h> #include <pinmux.h>
#define USART_CALLBACK_MODE true
#if USART_CALLBACK_MODE == true #if USART_CALLBACK_MODE == true
# include <sercom_interrupt.h> # include <sercom_interrupt.h>
#endif #endif

View File

@ -20,10 +20,6 @@
#include "compiler.h" #include "compiler.h"
#include "port.h" #include "port.h"
void pin_mode(PinName pin, PinMode mode) { // Kept as dummy function. configuration settings already taken care in gpio_dir function
MBED_ASSERT(pin != (PinName)NC);
}
uint32_t gpio_set(PinName pin) { uint32_t gpio_set(PinName pin) {
MBED_ASSERT(pin != (PinName)NC); MBED_ASSERT(pin != (PinName)NC);
return (1UL << (pin % 32)); return (1UL << (pin % 32));
@ -41,6 +37,8 @@ void gpio_init(gpio_t *obj, PinName pin) {
obj->mask = gpio_set(pin); obj->mask = gpio_set(pin);
port_get_config_defaults(&pin_conf); port_get_config_defaults(&pin_conf);
obj->powersave = pin_conf.powersave; obj->powersave = pin_conf.powersave;
obj->direction = PORT_PIN_DIR_INPUT;
obj->mode = PORT_PIN_PULL_UP;
port_pin_set_config(pin, &pin_conf); port_pin_set_config(pin, &pin_conf);
obj->OUTCLR = &port_base->OUTCLR.reg; obj->OUTCLR = &port_base->OUTCLR.reg;
@ -49,24 +47,43 @@ void gpio_init(gpio_t *obj, PinName pin) {
} }
void gpio_mode(gpio_t *obj, PinMode mode) { void gpio_mode(gpio_t *obj, PinMode mode) {
pin_mode(obj->pin, mode); MBED_ASSERT(obj->pin != (PinName)NC);
struct port_config pin_conf;
obj->mode = mode;
pin_conf.direction = obj->direction;
pin_conf.powersave = obj->powersave;
switch (mode) {
case PullNone :
pin_conf.input_pull = PORT_PIN_PULL_NONE;
break;
case PullUp:
pin_conf.input_pull = PORT_PIN_PULL_UP;
break;
case PullDown:
pin_conf.input_pull = PORT_PIN_PULL_DOWN;
break;
}
port_pin_set_config(obj->pin, &pin_conf);
} }
void gpio_dir(gpio_t *obj, PinDirection direction) { void gpio_dir(gpio_t *obj, PinDirection direction) {
MBED_ASSERT(obj->pin != (PinName)NC); MBED_ASSERT(obj->pin != (PinName)NC);
struct port_config pin_conf; struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
obj->direction = direction;
pin_conf.input_pull = obj->mode;
pin_conf.powersave = obj->powersave;
switch (direction) { switch (direction) {
case PIN_INPUT : case PIN_INPUT :
pin_conf.direction = PORT_PIN_DIR_INPUT; pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_UP; break;
break;
case PIN_OUTPUT: case PIN_OUTPUT:
pin_conf.direction = PORT_PIN_DIR_OUTPUT; pin_conf.direction = PORT_PIN_DIR_OUTPUT;
break; break;
case PIN_INPUT_OUTPUT: case PIN_INPUT_OUTPUT:
pin_conf.direction = PORT_PIN_DIR_OUTPUT; pin_conf.direction = PORT_PIN_DIR_OUTPUT_WTH_READBACK;
break; break;
} }
port_pin_set_config(obj->pin, &pin_conf); port_pin_set_config(obj->pin, &pin_conf);
} }

View File

@ -26,7 +26,9 @@ typedef struct {
PinName pin; PinName pin;
uint32_t mask; uint32_t mask;
uint8_t powersave; uint8_t powersave;
uint8_t mode;
uint8_t direction;
__IO uint32_t *OUTCLR; __IO uint32_t *OUTCLR;
__IO uint32_t *OUTSET; __IO uint32_t *OUTSET;
__I uint32_t *IN; __I uint32_t *IN;

View File

@ -41,8 +41,29 @@ struct port_s {
}; };
struct serial_s { struct serial_s {
SercomUsart *uart; Sercom *usart;
int index; uint32_t index;
uint32_t data_order;
uint32_t transfer_mode;
uint32_t parity;
uint32_t stopbits;
uint32_t character_size;
uint32_t mux_setting;
uint32_t sample_rate;
uint32_t sample_adjustment;
uint8_t start_frame_detection_enable;
uint32_t baudrate;
uint32_t receiver_enable;
uint32_t transmitter_enable;
uint32_t clock_polarity_inverted;
uint8_t use_external_clock;
uint32_t ext_clock_freq;
uint8_t run_in_standby;
uint32_t generator_source;
uint32_t pinmux_pad0;
uint32_t pinmux_pad1;
uint32_t pinmux_pad2;
uint32_t pinmux_pad3;
}; };
/* /*
struct pwmout_s { struct pwmout_s {

View File

@ -13,43 +13,94 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#include <string.h>
#include "mbed_assert.h" #include "mbed_assert.h"
#include "cmsis.h" #include "cmsis.h"
#include "serial_api.h" #include "serial_api.h"
#include <string.h>
#include "pinmap.h" #include "pinmap.h"
#include "PeripheralPins.h" #include "PeripheralPins.h"
#include "usart.h" #include "usart.h"
#include "usart_interrupt.h"
#include "samr21_xplained_pro.h" #include "samr21_xplained_pro.h"
#define UART_NUM 1 // for SAMR21 // to be updated for samd21 #define _USART(obj) obj->usart->USART
#define USART_NUM 1 // for SAMR21 // to be updated for samd21
//#define USART_BUF 8
struct usart_module usart_instance; static uint32_t serial_irq_ids[USART_NUM] = {0};
static uint32_t serial_irq_ids[UART_NUM] = {0};
static uart_irq_handler irq_handler; static uart_irq_handler irq_handler;
int stdio_uart_inited = 0; int stdio_uart_inited = 0;
serial_t stdio_uart; serial_t stdio_uart;
/**
* \internal /*struct serial_global_data_s{
* Set Configuration of the USART module uint8_t string[USART_BUF];
*/ uint8_t count;
static enum status_code _usart_set_config( };
struct usart_module *const module, static struct serial_global_data_s uart_data[USART_NUM];*/
const struct usart_config *const config)
extern uint8_t g_sys_init;
static inline bool usart_syncing(serial_t *obj)
{ {
/* Sanity check arguments */ /* Sanity check arguments */
Assert(module); MBED_ASSERT(obj);
Assert(module->hw);
/* Get a pointer to the hardware module instance */ return (_USART(obj).SYNCBUSY.reg);
SercomUsart *const usart_hw = &(module->hw->USART); }
/* Index for generic clock */ static inline void enable_usart(serial_t *obj)
uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw); {
/* Sanity check arguments */
MBED_ASSERT(obj);
#if USART_CALLBACK_MODE == true //TODO: to be implemented
/* Enable Global interrupt for module */
system_interrupt_enable(_sercom_get_interrupt_vector(obj->usart));
#endif
/* Wait until synchronization is complete */
usart_syncing(obj);
/* Enable USART module */
_USART(obj).CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}
static inline void disable_usart(serial_t *obj)
{
/* Sanity check arguments */
MBED_ASSERT(obj);
#if USART_CALLBACK_MODE == true //TODO: to be implemented
/* Disable Global interrupt for module */
system_interrupt_disable(_sercom_get_interrupt_vector(obj->usart));
#endif
/* Wait until synchronization is complete */
usart_syncing(obj);
/* Disable USART module */
_USART(obj).CTRLA.reg &= ~SERCOM_USART_CTRLA_ENABLE;
}
static inline void reset_usart(serial_t *obj)
{
/* Sanity check arguments */
MBED_ASSERT(obj);
disable_usart(obj);
/* Wait until synchronization is complete */
usart_syncing(obj);
/* Reset module */
_USART(obj).CTRLA.reg = SERCOM_USART_CTRLA_SWRST;
}
static enum status_code usart_set_config_asf( serial_t *obj)
{
/* Index for generic clock */
uint32_t sercom_index = _sercom_get_sercom_inst_index(obj->usart);
uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE; uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
/* Cache new register values to minimize the number of register writes */ /* Cache new register values to minimize the number of register writes */
@ -60,92 +111,48 @@ static enum status_code _usart_set_config(
enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC; enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16; enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
#ifdef FEATURE_USART_OVER_SAMPLE
switch (config->sample_rate) {
case USART_SAMPLE_RATE_16X_ARITHMETIC:
mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
break;
case USART_SAMPLE_RATE_8X_ARITHMETIC:
mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
sample_num = SERCOM_ASYNC_SAMPLE_NUM_8;
break;
case USART_SAMPLE_RATE_3X_ARITHMETIC:
mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
sample_num = SERCOM_ASYNC_SAMPLE_NUM_3;
break;
case USART_SAMPLE_RATE_16X_FRACTIONAL:
mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL;
sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
break;
case USART_SAMPLE_RATE_8X_FRACTIONAL:
mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL;
sample_num = SERCOM_ASYNC_SAMPLE_NUM_8;
break;
}
#endif
/* Set data order, internal muxing, and clock polarity */ /* Set data order, internal muxing, and clock polarity */
ctrla = (uint32_t)config->data_order | ctrla = (uint32_t)obj->data_order |
(uint32_t)config->mux_setting | (uint32_t)obj->mux_setting |
#ifdef FEATURE_USART_OVER_SAMPLE #ifdef FEATURE_USART_OVER_SAMPLE
config->sample_adjustment | obj->sample_adjustment |
config->sample_rate | obj->sample_rate |
#endif #endif
#ifdef FEATURE_USART_IMMEDIATE_BUFFER_OVERFLOW_NOTIFICATION (obj->clock_polarity_inverted << SERCOM_USART_CTRLA_CPOL_Pos);
(config->immediate_buffer_overflow_notification << SERCOM_USART_CTRLA_IBON_Pos) |
#endif
(config->clock_polarity_inverted << SERCOM_USART_CTRLA_CPOL_Pos);
enum status_code status_code = STATUS_OK;
/* Get baud value from mode and clock */ /* Get baud value from mode and clock */
switch (config->transfer_mode) switch (obj->transfer_mode)
{ {
case USART_TRANSFER_SYNCHRONOUSLY: case USART_TRANSFER_SYNCHRONOUSLY:
if (!config->use_external_clock) { if (!obj->use_external_clock) {
status_code = _sercom_get_sync_baud_val(config->baudrate, _sercom_get_sync_baud_val(obj->baudrate,
system_gclk_chan_get_hz(gclk_index), &baud); system_gclk_chan_get_hz(gclk_index), &baud);
} }
break; break;
case USART_TRANSFER_ASYNCHRONOUSLY: case USART_TRANSFER_ASYNCHRONOUSLY:
if (config->use_external_clock) { if (obj->use_external_clock) {
status_code = _sercom_get_async_baud_val(obj->baudrate,
_sercom_get_async_baud_val(config->baudrate, obj->ext_clock_freq, &baud, mode, sample_num);
config->ext_clock_freq, &baud, mode, sample_num);
} else { } else {
status_code = _sercom_get_async_baud_val(obj->baudrate,
_sercom_get_async_baud_val(config->baudrate,
system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num); system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
} }
break; break;
} }
/* Check if calculating the baudrate failed */
if (status_code != STATUS_OK) {
/* Abort */
return status_code;
}
#ifdef FEATURE_USART_IRDA
if(config->encoding_format_enable) {
usart_hw->RXPL.reg = config->receive_pulse_length;
}
#endif
/* Wait until synchronization is complete */ /* Wait until synchronization is complete */
_usart_wait_for_sync(module); usart_syncing(obj);
/*Set baud val */ /*Set baud val */
usart_hw->BAUD.reg = baud; _USART(obj).BAUD.reg = baud;
/* Set sample mode */ /* Set sample mode */
ctrla |= config->transfer_mode; ctrla |= obj->transfer_mode;
if (config->use_external_clock == false) { if (obj->use_external_clock == false) {
ctrla |= SERCOM_USART_CTRLA_MODE(0x1); ctrla |= SERCOM_USART_CTRLA_MODE(0x1);
} }
else { else {
@ -153,140 +160,122 @@ static enum status_code _usart_set_config(
} }
/* Set stopbits, character size and enable transceivers */ /* Set stopbits, character size and enable transceivers */
ctrlb = (uint32_t)config->stopbits | (uint32_t)config->character_size | ctrlb = (uint32_t)obj->stopbits | (uint32_t)obj->character_size |
#ifdef FEATURE_USART_IRDA
(config->encoding_format_enable << SERCOM_USART_CTRLB_ENC_Pos) |
#endif
#ifdef FEATURE_USART_START_FRAME_DECTION #ifdef FEATURE_USART_START_FRAME_DECTION
(config->start_frame_detection_enable << SERCOM_USART_CTRLB_SFDE_Pos) | (obj->start_frame_detection_enable << SERCOM_USART_CTRLB_SFDE_Pos) |
#endif #endif
#ifdef FEATURE_USART_COLLISION_DECTION (obj->receiver_enable << SERCOM_USART_CTRLB_RXEN_Pos) |
(config->collision_detection_enable << SERCOM_USART_CTRLB_COLDEN_Pos) | (obj->transmitter_enable << SERCOM_USART_CTRLB_TXEN_Pos);
#endif
(config->receiver_enable << SERCOM_USART_CTRLB_RXEN_Pos) |
(config->transmitter_enable << SERCOM_USART_CTRLB_TXEN_Pos);
/* Check parity mode bits */ /* Check parity mode bits */
if (config->parity != USART_PARITY_NONE) { if (obj->parity != USART_PARITY_NONE) {
#ifdef FEATURE_USART_LIN_SLAVE
if(config->lin_slave_enable) {
ctrla |= SERCOM_USART_CTRLA_FORM(0x5);
} else {
ctrla |= SERCOM_USART_CTRLA_FORM(1);
}
#else
ctrla |= SERCOM_USART_CTRLA_FORM(1); ctrla |= SERCOM_USART_CTRLA_FORM(1);
#endif ctrlb |= obj->parity;
ctrlb |= config->parity;
} else { } else {
#ifdef FEATURE_USART_LIN_SLAVE
if(config->lin_slave_enable) {
ctrla |= SERCOM_USART_CTRLA_FORM(0x4);
} else {
ctrla |= SERCOM_USART_CTRLA_FORM(0);
}
#else
ctrla |= SERCOM_USART_CTRLA_FORM(0); ctrla |= SERCOM_USART_CTRLA_FORM(0);
#endif
} }
/* Set whether module should run in standby. */ /* Set whether module should run in standby. */
if (config->run_in_standby || system_is_debugger_present()) { if (obj->run_in_standby || system_is_debugger_present()) {
ctrla |= SERCOM_USART_CTRLA_RUNSTDBY; ctrla |= SERCOM_USART_CTRLA_RUNSTDBY;
} }
/* Wait until synchronization is complete */ /* Wait until synchronization is complete */
_usart_wait_for_sync(module); usart_syncing(obj);
/* Write configuration to CTRLB */ /* Write configuration to CTRLB */
usart_hw->CTRLB.reg = ctrlb; _USART(obj).CTRLB.reg = ctrlb;
/* Wait until synchronization is complete */ /* Wait until synchronization is complete */
_usart_wait_for_sync(module); usart_syncing(obj);
/* Write configuration to CTRLA */ /* Write configuration to CTRLA */
usart_hw->CTRLA.reg = ctrla; _USART(obj).CTRLA.reg = ctrla;
return STATUS_OK; return STATUS_OK;
} }
void serial_init(serial_t *obj, PinName tx, PinName rx) { void serial_init(serial_t *obj, PinName tx, PinName rx) {
if (g_sys_init == 0) {
struct usart_config config_usart; system_init();
g_sys_init = 1;
}
struct system_gclk_chan_config gclk_chan_conf; struct system_gclk_chan_config gclk_chan_conf;
uint32_t gclk_index; uint32_t gclk_index;
uint32_t pm_index; uint32_t pm_index;
uint32_t sercom_index = 0; // index 0 for SERCOM0 uint32_t sercom_index = 0;
enum status_code status_code = STATUS_OK;
usart_get_config_defaults(&config_usart); // get default configuration setting used below obj->usart = EXT1_UART_MODULE;
config_usart.baudrate = 9600; // setting default configurations for SERCOM0 serial /* Disable USART module */
config_usart.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING; disable_usart(obj);
config_usart.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
config_usart.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1; /* Set default config to object */
config_usart.pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2; obj->data_order = USART_DATAORDER_LSB;
config_usart.pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3; obj->transfer_mode = USART_TRANSFER_ASYNCHRONOUSLY;
obj->parity = USART_PARITY_NONE;
obj->stopbits = USART_STOPBITS_1;
obj->character_size = USART_CHARACTER_SIZE_8BIT;
obj->baudrate = 9600;
obj->receiver_enable = true;
obj->transmitter_enable = true;
obj->clock_polarity_inverted = false;
obj->use_external_clock = false;
obj->ext_clock_freq = 0;
obj->mux_setting = USART_RX_1_TX_2_XCK_3;
obj->run_in_standby = false;
obj->generator_source = GCLK_GENERATOR_0;
obj->pinmux_pad0 = PINMUX_DEFAULT;
obj->pinmux_pad1 = PINMUX_DEFAULT;
obj->pinmux_pad2 = PINMUX_DEFAULT;
obj->pinmux_pad3 = PINMUX_DEFAULT;
obj->start_frame_detection_enable = false;
obj->mux_setting = EDBG_CDC_SERCOM_MUX_SETTING; // to be done according to the pin received from user
obj->pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
obj->pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1;
obj->pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2;
obj->pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3;
//TODO: now noly UART0. code to get the SERCOM instance from Pins (pinmapping) to be added later //TODO: now noly UART0. code to get the SERCOM instance from Pins (pinmapping) to be added later
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
obj->uart = (SercomUsart *)uart; sercom_index = _sercom_get_sercom_inst_index(obj->usart);
usart_instance.hw = (Sercom *)uart;
pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos;
pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos; gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
if (obj->uart->CTRLA.reg & SERCOM_USART_CTRLA_SWRST) { if (_USART(obj).CTRLA.reg & SERCOM_USART_CTRLA_SWRST) {
/* The module is busy resetting itself */ /* The module is busy resetting itself */
return;
} }
if (obj->uart->CTRLA.reg & SERCOM_USART_CTRLA_ENABLE) { if (_USART(obj).CTRLA.reg & SERCOM_USART_CTRLA_ENABLE) {
/* Check the module is enabled */ /* Check the module is enabled */
return;
} }
/* Turn on module in PM */ /* Turn on module in PM */
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index); system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
/* Set up the GCLK for the module */ /* Set up the GCLK for the module */
system_gclk_chan_get_config_defaults(&gclk_chan_conf); obj->generator_source = GCLK_GENERATOR_0;
gclk_chan_conf.source_generator = config_usart.generator_source; gclk_chan_conf.source_generator = obj->generator_source;
system_gclk_chan_set_config(gclk_index, &gclk_chan_conf); system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
system_gclk_chan_enable(gclk_index); system_gclk_chan_enable(gclk_index);
sercom_set_gclk_generator(config_usart.generator_source, false); sercom_set_gclk_generator(obj->generator_source, false);
/* Set character size */
usart_instance.character_size = config_usart.character_size;
/* Set transmitter and receiver status */
usart_instance.receiver_enabled = config_usart.receiver_enable;
usart_instance.transmitter_enabled = config_usart.transmitter_enable;
#ifdef FEATURE_USART_LIN_SLAVE
usart_instance.lin_slave_enabled = config_usart.lin_slave_enable;
#endif
#ifdef FEATURE_USART_START_FRAME_DECTION
usart_instance.start_frame_detection_enabled = config_usart.start_frame_detection_enable;
#endif
/* Set configuration according to the config struct */
status_code = _usart_set_config(&usart_instance, &config_usart);
if(status_code != STATUS_OK) {
return;
}
/* Set configuration according to the config struct */
usart_set_config_asf(obj);
struct system_pinmux_config pin_conf; struct system_pinmux_config pin_conf;
system_pinmux_get_config_defaults(&pin_conf); system_pinmux_get_config_defaults(&pin_conf);
pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT; pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE; pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
uint32_t pad_pinmuxes[] = { uint32_t pad_pinmuxes[] = {
config_usart.pinmux_pad0, config_usart.pinmux_pad1, obj->pinmux_pad0, obj->pinmux_pad1,
config_usart.pinmux_pad2, config_usart.pinmux_pad3 obj->pinmux_pad2, obj->pinmux_pad3
}; };
/* Configure the SERCOM pins according to the user configuration */ /* Configure the SERCOM pins according to the user configuration */
@ -294,7 +283,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
uint32_t current_pinmux = pad_pinmuxes[pad]; uint32_t current_pinmux = pad_pinmuxes[pad];
if (current_pinmux == PINMUX_DEFAULT) { if (current_pinmux == PINMUX_DEFAULT) {
current_pinmux = _sercom_get_default_pad(usart_instance.hw, pad); current_pinmux = _sercom_get_default_pad(obj->usart, pad);
} }
if (current_pinmux != PINMUX_UNUSED) { if (current_pinmux != PINMUX_UNUSED) {
@ -308,111 +297,195 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
memcpy(&stdio_uart, obj, sizeof(serial_t)); memcpy(&stdio_uart, obj, sizeof(serial_t));
} }
system_interrupt_enable(_sercom_get_interrupt_vector(usart_instance.hw));
/* Wait until synchronization is complete */ /* Wait until synchronization is complete */
_usart_wait_for_sync(&usart_instance); usart_syncing(obj);
/* Enable USART module */ /* Enable USART module */
obj->uart->CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE; enable_usart(obj);
/* usart_get_config_defaults(&config_usart);
config_usart.baudrate = 9600;
config_usart.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING;
config_usart.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
config_usart.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1;
config_usart.pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2;
config_usart.pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3;
while (usart_init(&usart_instance,
EDBG_CDC_MODULE, &config_usart) != STATUS_OK) {
}*/
} }
/*
void serial_free(serial_t *obj) { void serial_free(serial_t *obj) {
serial_irq_ids[obj->index] = 0; serial_irq_ids[obj->index] = 0;
}*/ }
void serial_baud(serial_t *obj, int baudrate) { void serial_baud(serial_t *obj, int baudrate) {
/* struct usart_config config_usart; MBED_ASSERT((baudrate == 110) || (baudrate == 150) || (baudrate == 300) || (baudrate == 1200) ||
(baudrate == 2400) || (baudrate == 4800) || (baudrate == 9600) || (baudrate == 19200) || (baudrate == 38400) ||
(baudrate == 57600) || (baudrate == 115200) || (baudrate == 230400) || (baudrate == 460800) || (baudrate == 921600) );
struct system_gclk_chan_config gclk_chan_conf;
uint32_t gclk_index;
uint16_t baud = 0;
uint32_t sercom_index = 0;
enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
usart_get_config_defaults(&config_usart); obj->baudrate = baudrate;
config_usart.baudrate = baudrate; disable_usart(obj);
while (usart_init(&usart_instance,
EDBG_CDC_MODULE, &config_usart) != STATUS_OK) { sercom_index = _sercom_get_sercom_inst_index(obj->usart);
}*/ gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
obj->generator_source = GCLK_GENERATOR_0;
gclk_chan_conf.source_generator = obj->generator_source;
system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
system_gclk_chan_enable(gclk_index);
sercom_set_gclk_generator(obj->generator_source, false);
/* Get baud value from mode and clock */
switch (obj->transfer_mode)
{
case USART_TRANSFER_SYNCHRONOUSLY:
if (!obj->use_external_clock) {
_sercom_get_sync_baud_val(obj->baudrate,
system_gclk_chan_get_hz(gclk_index), &baud);
}
break;
case USART_TRANSFER_ASYNCHRONOUSLY:
if (obj->use_external_clock) {
_sercom_get_async_baud_val(obj->baudrate,
obj->ext_clock_freq, &baud, mode, sample_num);
} else {
_sercom_get_async_baud_val(obj->baudrate,
system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
}
break;
}
/* Wait until synchronization is complete */
usart_syncing(obj);
/*Set baud val */
_USART(obj).BAUD.reg = baud;
/* Wait until synchronization is complete */
usart_syncing(obj);
enable_usart(obj);
} }
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
/* struct usart_config config_usart;
MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); MBED_ASSERT((stop_bits == 1) || (stop_bits == 2));
MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven)); MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven));
MBED_ASSERT((data_bits == 5) || (data_bits == 6) || (data_bits == 7) || (data_bits == 8) || (data_bits == 9)); MBED_ASSERT((data_bits == 5) || (data_bits == 6) || (data_bits == 7) || (data_bits == 8) /*|| (data_bits == 9)*/);
/* Cache new register values to minimize the number of register writes */
uint32_t ctrla = 0;
uint32_t ctrlb = 0;
usart_get_config_defaults(&config_usart); disable_usart(obj);
ctrla = _USART(obj).CTRLA.reg;
ctrlb = _USART(obj).CTRLB.reg;
ctrla &= ~(SERCOM_USART_CTRLA_FORM_Msk);
ctrlb &= ~(SERCOM_USART_CTRLB_CHSIZE_Msk);
ctrlb &= ~(SERCOM_USART_CTRLB_SBMODE);
ctrlb &= ~(SERCOM_USART_CTRLB_PMODE);
switch (stop_bits){ switch (stop_bits){
case 1: case 1:
config_usart.stopbits = USART_STOPBITS_1; obj->stopbits = USART_STOPBITS_1;
break; break;
case 2: case 2:
config_usart.stopbits = USART_STOPBITS_2; obj->stopbits = USART_STOPBITS_2;
break; break;
default: default:
config_usart.stopbits = USART_STOPBITS_1; obj->stopbits = USART_STOPBITS_1;
} }
switch (parity){ switch (parity){
case ParityNone: case ParityNone:
config_usart.parity = USART_PARITY_NONE; obj->parity = USART_PARITY_NONE;
break; break;
case ParityOdd: case ParityOdd:
config_usart.parity = USART_PARITY_ODD; obj->parity = USART_PARITY_ODD;
break; break;
case ParityEven: case ParityEven:
config_usart.parity = USART_PARITY_EVEN; obj->parity = USART_PARITY_EVEN;
break; break;
default: default:
config_usart.parity = USART_PARITY_NONE; obj->parity = USART_PARITY_NONE;
} }
switch (data_bits){ switch (data_bits){
case 5: case 5:
config_usart.character_size = USART_CHARACTER_SIZE_5BIT; obj->character_size = USART_CHARACTER_SIZE_5BIT;
break; break;
case 6: case 6:
config_usart.character_size = USART_CHARACTER_SIZE_6BIT; obj->character_size = USART_CHARACTER_SIZE_6BIT;
break; break;
case 7: case 7:
config_usart.character_size = USART_CHARACTER_SIZE_7BIT; obj->character_size = USART_CHARACTER_SIZE_7BIT;
break; break;
case 8: case 8:
config_usart.character_size = USART_CHARACTER_SIZE_8BIT; obj->character_size = USART_CHARACTER_SIZE_8BIT;
break;
case 9:
config_usart.character_size = USART_CHARACTER_SIZE_9BIT;
break; break;
/*case 9:
obj->character_size = USART_CHARACTER_SIZE_9BIT;
break;*/
default: default:
config_usart.character_size = USART_CHARACTER_SIZE_8BIT; obj->character_size = USART_CHARACTER_SIZE_8BIT;
} }
while (usart_init(&usart_instance,
EDBG_CDC_MODULE, &config_usart) != STATUS_OK) { /* Set stopbits, character size and enable transceivers */
}*/ ctrlb = (uint32_t)obj->stopbits | (uint32_t)obj->character_size;
/* Check parity mode bits */
if (obj->parity != USART_PARITY_NONE) {
ctrla |= SERCOM_USART_CTRLA_FORM(1);
ctrlb |= obj->parity;
} else {
ctrla |= SERCOM_USART_CTRLA_FORM(0);
}
/* Write configuration to CTRLB */
_USART(obj).CTRLB.reg = ctrlb;
/* Wait until synchronization is complete */
usart_syncing(obj);
/* Write configuration to CTRLA */
_USART(obj).CTRLA.reg = ctrla;
/* Wait until synchronization is complete */
usart_syncing(obj);
enable_usart(obj);
} }
/****************************************************************************** /******************************************************************************
* INTERRUPTS HANDLING * INTERRUPTS HANDLING
******************************************************************************/ ******************************************************************************/
static inline void uart_irq(SercomUsart *const uart, uint32_t index) { static inline void uart_irq(SercomUsart *const usart, uint32_t index) {
uint16_t interrupt_status; uint16_t interrupt_status;
/* Read and mask interrupt flag register */ interrupt_status = usart->INTFLAG.reg;
interrupt_status = uart->INTFLAG.reg; interrupt_status &= usart->INTENSET.reg;
interrupt_status &= uart->INTENSET.reg;
if (serial_irq_ids[index] != 0) { if (serial_irq_ids[index] != 0) {
if (interrupt_status & /*SERCOM_USART_INTFLAG_TXC*/SERCOM_USART_INTFLAG_DRE) // for transmit complete if (interrupt_status & SERCOM_USART_INTFLAG_TXC) // for transmit complete
{
usart->INTENCLR.reg = SERCOM_USART_INTFLAG_TXC;
irq_handler(serial_irq_ids[index], TxIrq); irq_handler(serial_irq_ids[index], TxIrq);
if (interrupt_status & SERCOM_USART_INTFLAG_RXC) // for recieve complete }
/*if (interrupt_status & SERCOM_USART_INTFLAG_DRE) // for data ready for transmit
{
if (uart_data[index].count > 0){
usart->DATA.reg = uart_data[index].string[uart_data[index].count];
uart_data[index].count--;
}
if(uart_data[index].count == 0){
usart->INTENCLR.reg = SERCOM_USART_INTFLAG_DRE;
usart->INTENSET.reg = SERCOM_USART_INTFLAG_TXC;
} else {
usart->INTENCLR.reg = SERCOM_USART_INTFLAG_DRE;
}
}*/
if (interrupt_status & SERCOM_USART_INTFLAG_RXC) // for receive complete
{
usart->INTENCLR.reg = SERCOM_USART_INTFLAG_RXC;
irq_handler(serial_irq_ids[index], RxIrq); irq_handler(serial_irq_ids[index], RxIrq);
}
} }
} }
@ -434,92 +507,249 @@ void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
IRQn_Type irq_n = (IRQn_Type)0; IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0; uint32_t vector = 0;
switch ((int)obj->uart) { uint32_t ctrlb = 0;
disable_usart(obj);
ctrlb = _USART(obj).CTRLB.reg;
switch ((int)obj->usart) {
case UART_0: case UART_0:
irq_n = (uint32_t)&SERCOM0_Handler; irq_n = SERCOM0_IRQn;
vector = (uint32_t)&uart0_irq; vector = (uint32_t)&uart0_irq;
break; break;
} }
if (enable) { if (enable) {
// usart_enable(&usart_instance);
switch (irq){ switch (irq){
case RxIrq: obj->uart->INTENSET.reg |= SERCOM_USART_INTENSET_RXC; break; case RxIrq:
case TxIrq: obj->uart->INTENSET.reg |= /*SERCOM_USART_INTENSET_TXC*/SERCOM_USART_INTFLAG_DRE; break; ctrlb |= (SERCOM_USART_CTRLB_RXEN);
break;
case TxIrq:
ctrlb |= (SERCOM_USART_CTRLB_TXEN);
break;
} }
/* switch (irq) {
case RxIrq: obj->uart->C2 |= (UARTLP_C2_RIE_MASK); break;
case TxIrq: obj->uart->C2 |= (UARTLP_C2_TIE_MASK); break;
}*/
NVIC_SetVector(irq_n, vector); NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n); NVIC_EnableIRQ(irq_n);
} else { // disable } else {
// usart_disable(&usart_instance);
// int all_disabled = 0;
// SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
switch (irq) { switch (irq) {
case RxIrq: obj->uart->INTENCLR.reg &= ~(SERCOM_USART_INTENCLR_RXC); break; case RxIrq:
case TxIrq: obj->uart->INTENCLR.reg &= ~(/*SERCOM_USART_INTENCLR_TXC*/SERCOM_USART_INTFLAG_DRE); break; ctrlb &= ~(SERCOM_USART_CTRLB_RXEN);
break;
break;
case TxIrq:
ctrlb &= ~(SERCOM_USART_CTRLB_TXEN);
break;
} }
NVIC_DisableIRQ(irq_n); NVIC_DisableIRQ(irq_n);
/*int all_disabled = 0;
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
switch (irq) {
case RxIrq: obj->uart->C2 &= ~(UARTLP_C2_RIE_MASK); break;
case TxIrq: obj->uart->C2 &= ~(UARTLP_C2_TIE_MASK); break;
}
switch (other_irq) {
case RxIrq: all_disabled = (obj->uart->C2 & (UARTLP_C2_RIE_MASK)) == 0; break;
case TxIrq: all_disabled = (obj->uart->C2 & (UARTLP_C2_TIE_MASK)) == 0; break;
}
if (all_disabled)
NVIC_DisableIRQ(irq_n);*/
} }
_USART(obj).CTRLB.reg = ctrlb;
enable_usart(obj);
} }
/****************************************************************************** /******************************************************************************
* READ/WRITE * READ/WRITE
******************************************************************************/ ******************************************************************************/
int serial_getc(serial_t *obj) { int serial_getc(serial_t *obj) {
_USART(obj).INTENSET.reg = SERCOM_USART_INTFLAG_RXC; // test
while (!serial_readable(obj)); while (!serial_readable(obj));
return obj->uart->DATA.reg ; return _USART(obj).DATA.reg ;
// return obj->uart->D;
} }
void serial_putc(serial_t *obj, int c) { void serial_putc(serial_t *obj, int c) {
uint16_t q = (c & SERCOM_USART_DATA_MASK);
while (!serial_writable(obj)); while (!serial_writable(obj));
obj->uart->DATA.reg = (c & SERCOM_USART_DATA_MASK); // uart_data[obj->index].count++;
// obj->uart->D = c; // uart_data[obj->index].string[uart_data[obj->index].count] = q;
// _USART(obj).INTENSET.reg = SERCOM_USART_INTFLAG_DRE;
_USART(obj).DATA.reg = q;
while (!(_USART(obj).INTFLAG.reg & SERCOM_USART_INTFLAG_TXC)); // wait till data is sent
} }
int serial_readable(serial_t *obj) { int serial_readable(serial_t *obj) {
// check overrun uint32_t status = 1;
/*if (obj->uart->S1 & UARTLP_S1_OR_MASK) { if (!(_USART(obj).INTFLAG.reg & SERCOM_USART_INTFLAG_RXC)) {
obj->uart->S1 |= UARTLP_S1_OR_MASK; status = 0;
}*/ }
return 0/*(obj->uart->S1 & UARTLP_S1_RDRF_MASK)*/; else {
status = 1;
}
return status;
} }
int serial_writable(serial_t *obj) { int serial_writable(serial_t *obj) {
// check overrun uint32_t status = 1;
/*if (obj->uart->S1 & UARTLP_S1_OR_MASK) { if (!(_USART(obj).INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)) {
obj->uart->S1 |= UARTLP_S1_OR_MASK; status = 0;
}*/ }
return 0/*(obj->uart->S1 & UARTLP_S1_TDRE_MASK)*/; else {
status = 1;
}
return status;
} }
void serial_clear(serial_t *obj) { /************************************************************************************
* ASYNCHRONOUS HAL *
************************************************************************************/
#if DEVICE_SERIAL_ASYNCH
/************************************
* HELPER FUNCTIONS *
***********************************/
/** Configure TX events
*
* @param obj The serial object
* @param event The logical OR of the TX events to configure
* @param enable Set to non-zero to enable events, or zero to disable them
*/
void serial_tx_enable_event(serial_t *obj, int event, uint8_t enable)
{
} }
void serial_pinout_tx(PinName tx) { /**
// pinmap_pinout(tx, PinMap_UART_TX); * @param obj The serial object.
* @param event The logical OR of the RX events to configure
* @param enable Set to non-zero to enable events, or zero to disable them
*/
void serial_rx_enable_event(serial_t *obj, int event, uint8_t enable)
{
} }
void serial_break_set(serial_t *obj) { /** Configure the TX buffer for an asynchronous write serial transaction
// obj->uart->C2 |= UARTLP_C2_SBK_MASK; *
* @param obj The serial object.
* @param tx The buffer for sending.
* @param tx_length The number of words to transmit.
*/
void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t width)
{
} }
void serial_break_clear(serial_t *obj) { /** Configure the TX buffer for an asynchronous read serial transaction
// obj->uart->C2 &= ~UARTLP_C2_SBK_MASK; *
* @param obj The serial object.
* @param rx The buffer for receiving.
* @param rx_length The number of words to read.
*/
void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t width)
{
} }
/** Set character to be matched. If an event is enabled, and received character
* matches the defined char_match, the receiving process is stopped and MATCH event
* is invoked
*
* @param obj The serial object
* @param char_match A character in range 0-254
*/
void serial_set_char_match(serial_t *obj, uint8_t char_match)
{
}
/************************************
* TRANSFER FUNCTIONS *
***********************************/
/** Begin asynchronous TX transfer. The used buffer is specified in the serial object,
* tx_buff
*
* @param obj The serial object
* @param cb The function to call when an event occurs
* @param hint A suggestion for how to use DMA with this transfer
* @return Returns number of data transfered, or 0 otherwise
*/
int serial_tx_asynch(serial_t *obj, void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
{
}
/** Begin asynchronous RX transfer (enable interrupt for data collecting)
* The used buffer is specified in the serial object - rx_buff
*
* @param obj The serial object
* @param cb The function to call when an event occurs
* @param hint A suggestion for how to use DMA with this transfer
*/
void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
{
}
/** Attempts to determine if the serial peripheral is already in use for TX
*
* @param obj The serial object
* @return Non-zero if the TX transaction is ongoing, 0 otherwise
*/
uint8_t serial_tx_active(serial_t *obj)
{
}
/** Attempts to determine if the serial peripheral is already in use for RX
*
* @param obj The serial object
* @return Non-zero if the RX transaction is ongoing, 0 otherwise
*/
uint8_t serial_rx_active(serial_t *obj)
{
}
/** The asynchronous TX handler. Writes to the TX FIFO and checks for events.
* If any TX event has occured, the TX abort function is called.
*
* @param obj The serial object
* @return Returns event flags if a TX transfer termination condition was met or 0 otherwise
*/
int serial_tx_irq_handler_asynch(serial_t *obj)
{
}
/** The asynchronous RX handler. Reads from the RX FIFOF and checks for events.
* If any RX event has occured, the RX abort function is called.
*
* @param obj The serial object
* @return Returns event flags if a RX transfer termination condition was met or 0 otherwise
*/
int serial_rx_irq_handler_asynch(serial_t *obj)
{
}
/** Unified IRQ handler. Determines the appropriate handler to execute and returns the flags.
*
* WARNING: this code should be stateless, as re-entrancy is very possible in interrupt-based mode.
*/
int serial_irq_handler_asynch(serial_t *obj)
{
}
/** Abort the ongoing TX transaction. It disables the enabled interupt for TX and
* flush TX hardware buffer if TX FIFO is used
*
* @param obj The serial object
*/
void serial_tx_abort_asynch(serial_t *obj)
{
}
/** Abort the ongoing RX transaction It disables the enabled interrupt for RX and
* flush RX hardware buffer if RX FIFO is used
*
* @param obj The serial object
*/
void serial_rx_abort_asynch(serial_t *obj)
{
}
#endif

View File

@ -54,7 +54,7 @@ ARM_CPPLIB = join(ARM_LIB, "cpplib")
MY_ARM_CLIB = join(ARM_PATH, "lib", "microlib") MY_ARM_CLIB = join(ARM_PATH, "lib", "microlib")
# GCC ARM # GCC ARM
GCC_ARM_PATH = "C:/arm-gnu-toolchain/bin" GCC_ARM_PATH = "C:/Program Files/ARM/armcc_4.1_791"
# GCC CodeSourcery # GCC CodeSourcery
GCC_CS_PATH = "C:/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin" GCC_CS_PATH = "C:/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"