* updated serial_api.c and objects.h with optimisations.

pull/1214/head
akhilpanayamparambil 2015-06-24 19:06:22 +05:30 committed by Karthik Purushothaman
parent 705dc7afc7
commit afcfdfc8cf
4 changed files with 33 additions and 97 deletions

View File

@ -20,7 +20,7 @@
#include "pinmap.h" #include "pinmap.h"
#include "PeripheralNames.h" #include "PeripheralNames.h"
void find_pin_settings (PinName output, PinName input, PinName clock, uint32_t* pad_pinmuxes); void find_pin_settings (PinName output, PinName input, PinName clock, PinName chipsel, uint32_t* pad_pinmuxes); // clock also for RTS and chipsel for CTS
uint32_t find_mux_setting (PinName output, PinName input, PinName clock); uint32_t find_mux_setting (PinName output, PinName input, PinName clock);
/************RTC***************/ /************RTC***************/
//extern const PinMap PinMap_RTC[]; //extern const PinMap PinMap_RTC[];

View File

@ -457,9 +457,9 @@ uint32_t find_mux_setting (PinName output, PinName input, PinName clock)
break; break;
} }
if (((output_values.pad == 0) && (clock_values.pad == 1)) || (output_values.pad == 0)) { if (/*((output_values.pad == 0) && (clock_values.pad == 1)) ||*/ (output_values.pad == 0)) { // condition for hardware enable and usart is different
mux_setting |= SERCOM_USART_CTRLA_TXPO(0); mux_setting |= SERCOM_USART_CTRLA_TXPO(0);
} else if((output_values.pad == 2) && (clock_values.pad == 3)) { } else if(/*((output_values.pad == 2) && (clock_values.pad == 3)) ||*/ (output_values.pad == 2)) {
mux_setting |= SERCOM_USART_CTRLA_TXPO(1); mux_setting |= SERCOM_USART_CTRLA_TXPO(1);
} }
/*else if((output_values.pad == 0)) { // condition for hardware enabled /*else if((output_values.pad == 0)) { // condition for hardware enabled
@ -472,9 +472,9 @@ uint32_t find_mux_setting (PinName output, PinName input, PinName clock)
return mux_setting; return mux_setting;
} }
void find_pin_settings (PinName output, PinName input, PinName clock, uint32_t* pad_pinmuxes) void find_pin_settings (PinName output, PinName input, PinName clock, PinName chipsel, uint32_t* pad_pinmuxes)
{ {
struct pin_values input_values, output_values, clock_values; struct pin_values input_values, output_values, clock_values, chipsel_values;
uint8_t i = 0; uint8_t i = 0;
for (i = 0; i < 4 ; i++ ) { // load default values for the pins for (i = 0; i < 4 ; i++ ) { // load default values for the pins
@ -484,14 +484,17 @@ void find_pin_settings (PinName output, PinName input, PinName clock, uint32_t*
input_values.pin = input; input_values.pin = input;
output_values.pin = output; output_values.pin = output;
clock_values.pin = clock; clock_values.pin = clock;
chipsel_values.pin = chipsel;
input_values.com = pinmap_sercom_peripheral(input, output); input_values.com = pinmap_sercom_peripheral(input, output);
output_values.com = input_values.com; output_values.com = input_values.com;
clock_values.com = input_values.com; clock_values.com = input_values.com;
chipsel_values.com = input_values.com;
input_values.pad = pinmap_sercom_pad(input); input_values.pad = pinmap_sercom_pad(input);
output_values.pad = pinmap_sercom_pad(output); output_values.pad = pinmap_sercom_pad(output);
clock_values.pad = pinmap_sercom_pad(clock); clock_values.pad = pinmap_sercom_pad(clock);
chipsel_values.pad = pinmap_sercom_pad(chipsel);
if (input_values.pad < 0x04) if (input_values.pad < 0x04)
pad_pinmuxes[input_values.pad] = find_sercom_pinmux(&input_values); pad_pinmuxes[input_values.pad] = find_sercom_pinmux(&input_values);
@ -499,6 +502,8 @@ void find_pin_settings (PinName output, PinName input, PinName clock, uint32_t*
pad_pinmuxes[output_values.pad] = find_sercom_pinmux(&output_values); pad_pinmuxes[output_values.pad] = find_sercom_pinmux(&output_values);
if (clock_values.pad < 0x04) if (clock_values.pad < 0x04)
pad_pinmuxes[clock_values.pad] = find_sercom_pinmux(&clock_values); pad_pinmuxes[clock_values.pad] = find_sercom_pinmux(&clock_values);
if (chipsel_values.pad < 0x04)
pad_pinmuxes[chipsel_values.pad] = find_sercom_pinmux(&chipsel_values);
} }

View File

@ -43,23 +43,11 @@ struct port_s {
struct serial_s { struct serial_s {
Sercom *usart; Sercom *usart;
uint32_t index; uint32_t index;
uint32_t data_order;
uint32_t transfer_mode;
uint32_t parity; uint32_t parity;
uint32_t stopbits; uint32_t stopbits;
uint32_t character_size; uint32_t character_size;
uint32_t mux_setting; uint32_t mux_setting;
uint32_t sample_rate;
uint32_t sample_adjustment;
uint8_t start_frame_detection_enable;
uint32_t baudrate; 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_pad0;
uint32_t pinmux_pad1; uint32_t pinmux_pad1;
uint32_t pinmux_pad2; uint32_t pinmux_pad2;

View File

@ -98,7 +98,7 @@ static inline void reset_usart(serial_t *obj)
_USART(obj).CTRLA.reg = SERCOM_USART_CTRLA_SWRST; _USART(obj).CTRLA.reg = SERCOM_USART_CTRLA_SWRST;
} }
static enum status_code usart_set_config_asf( serial_t *obj) static enum status_code usart_set_config_default( serial_t *obj)
{ {
/* Index for generic clock */ /* Index for generic clock */
@ -114,35 +114,12 @@ static enum status_code usart_set_config_asf( serial_t *obj)
enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16; enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
/* Set data order, internal muxing, and clock polarity */ /* Set data order, internal muxing, and clock polarity */
ctrla = (uint32_t)pSERIAL_S(obj)->data_order | ctrla = (uint32_t)USART_DATAORDER_LSB | // data order
(uint32_t)pSERIAL_S(obj)->mux_setting | (uint32_t)pSERIAL_S(obj)->mux_setting; // mux setting // clock polarity is not used
#ifdef FEATURE_USART_OVER_SAMPLE
pSERIAL_S(obj)->sample_adjustment |
pSERIAL_S(obj)->sample_rate |
#endif
(pSERIAL_S(obj)->clock_polarity_inverted << SERCOM_USART_CTRLA_CPOL_Pos);
/* Get baud value from mode and clock */ /* Get baud value from mode and clock */
switch (pSERIAL_S(obj)->transfer_mode) { _sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate,system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num); // for asynchronous transfer mode
case USART_TRANSFER_SYNCHRONOUSLY:
if (!pSERIAL_S(obj)->use_external_clock) {
_sercom_get_sync_baud_val(pSERIAL_S(obj)->baudrate,
system_gclk_chan_get_hz(gclk_index), &baud);
}
break;
case USART_TRANSFER_ASYNCHRONOUSLY:
if (pSERIAL_S(obj)->use_external_clock) {
_sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate,
pSERIAL_S(obj)->ext_clock_freq, &baud, mode, sample_num);
} else {
_sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate,
system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
}
break;
}
/* Wait until synchronization is complete */ /* Wait until synchronization is complete */
usart_syncing(obj); usart_syncing(obj);
@ -151,21 +128,15 @@ static enum status_code usart_set_config_asf( serial_t *obj)
_USART(obj).BAUD.reg = baud; _USART(obj).BAUD.reg = baud;
/* Set sample mode */ /* Set sample mode */
ctrla |= pSERIAL_S(obj)->transfer_mode; ctrla |= USART_TRANSFER_ASYNCHRONOUSLY;
if (pSERIAL_S(obj)->use_external_clock == false) { /* for disabled external clock source */
ctrla |= SERCOM_USART_CTRLA_MODE(0x1); ctrla |= SERCOM_USART_CTRLA_MODE(0x1);
} else {
ctrla |= SERCOM_USART_CTRLA_MODE(0x0);
}
/* Set stopbits, character size and enable transceivers */ /* Set stopbits, character size and enable transceivers */
ctrlb = (uint32_t)pSERIAL_S(obj)->stopbits | (uint32_t)pSERIAL_S(obj)->character_size | ctrlb = (uint32_t)pSERIAL_S(obj)->stopbits | (uint32_t)pSERIAL_S(obj)->character_size |
#ifdef FEATURE_USART_START_FRAME_DECTION (0x1ul << SERCOM_USART_CTRLB_RXEN_Pos) | // receiver enable
(pSERIAL_S(obj)->start_frame_detection_enable << SERCOM_USART_CTRLB_SFDE_Pos) | (0x1ul << SERCOM_USART_CTRLB_TXEN_Pos); // transmitter enable
#endif
(pSERIAL_S(obj)->receiver_enable << SERCOM_USART_CTRLB_RXEN_Pos) |
(pSERIAL_S(obj)->transmitter_enable << SERCOM_USART_CTRLB_TXEN_Pos);
/* Check parity mode bits */ /* Check parity mode bits */
if (pSERIAL_S(obj)->parity != USART_PARITY_NONE) { if (pSERIAL_S(obj)->parity != USART_PARITY_NONE) {
@ -174,12 +145,7 @@ static enum status_code usart_set_config_asf( serial_t *obj)
} else { } else {
ctrla |= SERCOM_USART_CTRLA_FORM(0); ctrla |= SERCOM_USART_CTRLA_FORM(0);
} }
/* Set whether module should run in standby. */
if (pSERIAL_S(obj)->run_in_standby || system_is_debugger_present()) {
ctrla |= SERCOM_USART_CTRLA_RUNSTDBY;
}
/* Wait until synchronization is complete */ /* Wait until synchronization is complete */
usart_syncing(obj); usart_syncing(obj);
@ -198,25 +164,15 @@ static enum status_code usart_set_config_asf( serial_t *obj)
void get_default_serial_values(serial_t *obj) void get_default_serial_values(serial_t *obj)
{ {
/* Set default config to object */ /* Set default config to object */
pSERIAL_S(obj)->data_order = USART_DATAORDER_LSB;
pSERIAL_S(obj)->transfer_mode = USART_TRANSFER_ASYNCHRONOUSLY;
pSERIAL_S(obj)->parity = USART_PARITY_NONE; pSERIAL_S(obj)->parity = USART_PARITY_NONE;
pSERIAL_S(obj)->stopbits = USART_STOPBITS_1; pSERIAL_S(obj)->stopbits = USART_STOPBITS_1;
pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_8BIT; pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_8BIT;
pSERIAL_S(obj)->baudrate = 9600; pSERIAL_S(obj)->baudrate = 9600;
pSERIAL_S(obj)->receiver_enable = true;
pSERIAL_S(obj)->transmitter_enable = true;
pSERIAL_S(obj)->clock_polarity_inverted = false;
pSERIAL_S(obj)->use_external_clock = false;
pSERIAL_S(obj)->ext_clock_freq = 0;
pSERIAL_S(obj)->mux_setting = USART_RX_1_TX_2_XCK_3; pSERIAL_S(obj)->mux_setting = USART_RX_1_TX_2_XCK_3;
pSERIAL_S(obj)->run_in_standby = false;
pSERIAL_S(obj)->generator_source = GCLK_GENERATOR_0;
pSERIAL_S(obj)->pinmux_pad0 = PINMUX_DEFAULT; pSERIAL_S(obj)->pinmux_pad0 = PINMUX_DEFAULT;
pSERIAL_S(obj)->pinmux_pad1 = PINMUX_DEFAULT; pSERIAL_S(obj)->pinmux_pad1 = PINMUX_DEFAULT;
pSERIAL_S(obj)->pinmux_pad2 = PINMUX_DEFAULT; pSERIAL_S(obj)->pinmux_pad2 = PINMUX_DEFAULT;
pSERIAL_S(obj)->pinmux_pad3 = PINMUX_DEFAULT; pSERIAL_S(obj)->pinmux_pad3 = PINMUX_DEFAULT;
pSERIAL_S(obj)->start_frame_detection_enable = false;
}; };
@ -240,7 +196,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
get_default_serial_values(obj); get_default_serial_values(obj);
find_pin_settings(tx, rx, NC, &padsetting[0]); // tx, rx, clk, pad array // getting pads from pins find_pin_settings(tx, rx, NC, NC, &padsetting[0]); // tx, rx, clk, pad array // getting pads from pins
muxsetting = find_mux_setting(tx, rx, NC); // getting mux setting from pins muxsetting = find_mux_setting(tx, rx, NC); // getting mux setting from pins
sercom_index = pinmap_sercom_peripheral(tx, rx); // same variable sercom_index reused for optimization sercom_index = pinmap_sercom_peripheral(tx, rx); // same variable sercom_index reused for optimization
switch (sercom_index) { switch (sercom_index) {
@ -292,14 +248,13 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
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 */
pSERIAL_S(obj)->generator_source = GCLK_GENERATOR_0; gclk_chan_conf.source_generator = GCLK_GENERATOR_0;
gclk_chan_conf.source_generator = pSERIAL_S(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(pSERIAL_S(obj)->generator_source, false); sercom_set_gclk_generator(GCLK_GENERATOR_0, false);
/* Set configuration according to the config struct */ /* Set configuration according to the config struct */
usart_set_config_asf(obj); usart_set_config_default(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;
@ -361,31 +316,14 @@ void serial_baud(serial_t *obj, int baudrate)
sercom_index = _sercom_get_sercom_inst_index(pUSART_S(obj)); sercom_index = _sercom_get_sercom_inst_index(pUSART_S(obj));
gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE; gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
pSERIAL_S(obj)->generator_source = GCLK_GENERATOR_0; gclk_chan_conf.source_generator = GCLK_GENERATOR_0;
gclk_chan_conf.source_generator = pSERIAL_S(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(pSERIAL_S(obj)->generator_source, false); sercom_set_gclk_generator(GCLK_GENERATOR_0, false);
/* Get baud value from mode and clock */ /* Get baud value from mode and clock */
switch (pSERIAL_S(obj)->transfer_mode) { _sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate, system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
case USART_TRANSFER_SYNCHRONOUSLY:
if (!pSERIAL_S(obj)->use_external_clock) {
_sercom_get_sync_baud_val(pSERIAL_S(obj)->baudrate,
system_gclk_chan_get_hz(gclk_index), &baud);
}
break;
case USART_TRANSFER_ASYNCHRONOUSLY:
if (pSERIAL_S(obj)->use_external_clock) {
_sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate,
pSERIAL_S(obj)->ext_clock_freq, &baud, mode, sample_num);
} else {
_sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate,
system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
}
break;
}
/* Wait until synchronization is complete */ /* Wait until synchronization is complete */
usart_syncing(obj); usart_syncing(obj);
@ -486,6 +424,11 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
enable_usart(obj); enable_usart(obj);
} }
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
{
}
/****************************************************************************** /******************************************************************************
* INTERRUPTS HANDLING * INTERRUPTS HANDLING
******************************************************************************/ ******************************************************************************/