* updated functions for hardware flow control apis - not tested.

* updated sercom pin muxing to incorporate hardware flow control.
pull/1214/head
akhilpanayamparambil 2015-06-25 20:48:43 +05:30 committed by Karthik Purushothaman
parent a582b9f6a6
commit f55e6bd54a
4 changed files with 92 additions and 18 deletions

View File

@ -21,7 +21,7 @@
#include "PeripheralNames.h" #include "PeripheralNames.h"
void find_pin_settings (PinName output, PinName input, PinName clock, PinName chipsel, uint32_t* pad_pinmuxes); // clock also for RTS and chipsel for CTS 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, PinName chipsel);
/************RTC***************/ /************RTC***************/
//extern const PinMap PinMap_RTC[]; //extern const PinMap PinMap_RTC[];

View File

@ -425,22 +425,25 @@ uint32_t find_sercom_pinmux (struct pin_values* PinValues)
break; break;
} }
} }
uint32_t find_mux_setting (PinName output, PinName input, PinName clock) uint32_t find_mux_setting (PinName output, PinName input, PinName clock, PinName chipsel)
{ {
struct pin_values input_values, output_values, clock_values; struct pin_values input_values, output_values, clock_values, chipsel_values;
uint32_t mux_setting = 0; uint32_t mux_setting = 0;
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);
switch(input_values.pad) { //TODO: Condition for hardware flow control enabled is different. switch(input_values.pad) { //TODO: Condition for hardware flow control enabled is different.
case 0: case 0:
@ -457,18 +460,22 @@ 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)) { // condition for hardware enable and usart is different if ((clock == NC) && (chipsel == NC)) // condition for no hardware control and uart
mux_setting |= SERCOM_USART_CTRLA_TXPO(0); {
} else if(/*((output_values.pad == 2) && (clock_values.pad == 3)) ||*/ (output_values.pad == 2)) { if ((output_values.pad == 0)) { // condition for hardware enable and usart is different
mux_setting |= SERCOM_USART_CTRLA_TXPO(1); mux_setting |= SERCOM_USART_CTRLA_TXPO(0);
} } else if((output_values.pad == 2)) {
/*else if((output_values.pad == 0)) { // condition for hardware enabled mux_setting |= SERCOM_USART_CTRLA_TXPO(1);
mux_setting |= SERCOM_USART_CTRLA_TXPO(2); } else {
}*/ mux_setting = mux_setting; // dummy condition
else { }
mux_setting = mux_setting; // dummy condition }
} else { // for hardware flow control and uart // expecting the tx in pad 0, rts in pad2 and cts in pad 3
if((output_values.pad == 0) && (clock_values.pad/*rts pin*/ == 2) && (clock_values.pad/*cts pin*/ == 3)){
mux_setting |= SERCOM_USART_CTRLA_TXPO(2);
}
}
return mux_setting; return mux_setting;
} }

View File

@ -52,6 +52,8 @@ struct serial_s {
uint32_t pinmux_pad1; uint32_t pinmux_pad1;
uint32_t pinmux_pad2; uint32_t pinmux_pad2;
uint32_t pinmux_pad3; uint32_t pinmux_pad3;
PinName rxpin;
PinName txpin;
#if DEVICE_SERIAL_ASYNCH #if DEVICE_SERIAL_ASYNCH
uint32_t events; uint32_t events;
#endif #endif

View File

@ -196,8 +196,8 @@ 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, NC, &padsetting[0]); // tx, rx, clk, pad array // getting pads from pins find_pin_settings(tx, rx, NC, NC, &padsetting[0]); // tx, rx, clk(rts), chipsel(cts) 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, 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) {
case 0: case 0:
@ -226,6 +226,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
break; break;
} }
pSERIAL_S(obj)->txpin = tx;
pSERIAL_S(obj)->rxpin = rx;
pSERIAL_S(obj)->mux_setting = muxsetting;//EDBG_CDC_SERCOM_MUX_SETTING; pSERIAL_S(obj)->mux_setting = muxsetting;//EDBG_CDC_SERCOM_MUX_SETTING;
pSERIAL_S(obj)->pinmux_pad0 = padsetting[0];//EDBG_CDC_SERCOM_PINMUX_PAD0; pSERIAL_S(obj)->pinmux_pad0 = padsetting[0];//EDBG_CDC_SERCOM_PINMUX_PAD0;
pSERIAL_S(obj)->pinmux_pad1 = padsetting[1];//EDBG_CDC_SERCOM_PINMUX_PAD1; pSERIAL_S(obj)->pinmux_pad1 = padsetting[1];//EDBG_CDC_SERCOM_PINMUX_PAD1;
@ -424,11 +426,70 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
enable_usart(obj); enable_usart(obj);
} }
#ifdef DEVICE_SERIAL_FC
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
{ {
uint32_t muxsetting = 0;
uint32_t sercom_index = 0;
uint32_t padsetting[4] = {0};
disable_usart(obj);
//TODO : assert for rxflow and txflow pis to be added
find_pin_settings(pSERIAL_S(obj)->txpin, pSERIAL_S(obj)->rxpin, rxflow, txflow, &padsetting[0]); // tx, rx, clk(rts), chipsel(cts) pad array // getting pads from pins
muxsetting = find_mux_setting(pSERIAL_S(obj)->txpin, pSERIAL_S(obj)->rxpin, rxflow, txflow); // getting mux setting from pins
pSERIAL_S(obj)->mux_setting = muxsetting;//EDBG_CDC_SERCOM_MUX_SETTING;
pSERIAL_S(obj)->pinmux_pad0 = padsetting[0];//EDBG_CDC_SERCOM_PINMUX_PAD0;
pSERIAL_S(obj)->pinmux_pad1 = padsetting[1];//EDBG_CDC_SERCOM_PINMUX_PAD1;
pSERIAL_S(obj)->pinmux_pad2 = padsetting[2];//EDBG_CDC_SERCOM_PINMUX_PAD2;
pSERIAL_S(obj)->pinmux_pad3 = padsetting[3];//EDBG_CDC_SERCOM_PINMUX_PAD3;
struct system_pinmux_config pin_conf;
system_pinmux_get_config_defaults(&pin_conf);
pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
uint32_t pad_pinmuxes[] = {
pSERIAL_S(obj)->pinmux_pad0, pSERIAL_S(obj)->pinmux_pad1,
pSERIAL_S(obj)->pinmux_pad2, pSERIAL_S(obj)->pinmux_pad3
};
/* Configure the SERCOM pins according to the user configuration */
for (uint8_t pad = 0; pad < 4; pad++) {
uint32_t current_pinmux = pad_pinmuxes[pad];
if (current_pinmux == PINMUX_DEFAULT) {
current_pinmux = _sercom_get_default_pad(pUSART_S(obj), pad);
}
if (current_pinmux != PINMUX_UNUSED) {
pin_conf.mux_position = current_pinmux & 0xFFFF;
system_pinmux_pin_set_config(current_pinmux >> 16, &pin_conf);
}
}
enable_usart(obj);
} }
void serial_break_set(serial_t *obj)
{
disable_usart(obj);
_USART(obj).CTRLB.reg &= ~SERCOM_SPI_CTRLB_RXEN;
usart_syncing(obj);
enable_usart(obj);
}
void serial_break_clear(serial_t *obj)
{
disable_usart(obj);
_USART(obj).CTRLB.reg |= SERCOM_SPI_CTRLB_RXEN;
usart_syncing(obj);
enable_usart(obj);
}
#endif //DEVICE_SERIAL_FC
/****************************************************************************** /******************************************************************************
* INTERRUPTS HANDLING * INTERRUPTS HANDLING
******************************************************************************/ ******************************************************************************/
@ -897,6 +958,7 @@ int serial_irq_handler_asynch(serial_t *obj)
if(obj->tx_buff.pos >= obj->tx_buff.length) { if(obj->tx_buff.pos >= obj->tx_buff.length) {
/* Transfer complete. Switch off interrupt and return event. */ /* Transfer complete. Switch off interrupt and return event. */
_USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_DRE;
serial_tx_abort_asynch(obj); serial_tx_abort_asynch(obj);
return SERIAL_EVENT_TX_COMPLETE & obj->serial.events; return SERIAL_EVENT_TX_COMPLETE & obj->serial.events;
@ -925,8 +987,9 @@ int serial_irq_handler_asynch(serial_t *obj)
void serial_tx_abort_asynch(serial_t *obj) void serial_tx_abort_asynch(serial_t *obj)
{ {
//TODO: DMA to be implemented //TODO: DMA to be implemented
_USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_DRE;
_USART(obj).INTENSET.reg = SERCOM_USART_INTFLAG_TXC; _USART(obj).INTENSET.reg = SERCOM_USART_INTFLAG_TXC;
obj->tx_buff.pos = 0;
obj->tx_buff.length = 0;
} }
/** Abort the ongoing RX transaction It disables the enabled interrupt for RX and /** Abort the ongoing RX transaction It disables the enabled interrupt for RX and
* flush RX hardware buffer if RX FIFO is used * flush RX hardware buffer if RX FIFO is used
@ -937,6 +1000,8 @@ void serial_rx_abort_asynch(serial_t *obj)
{ {
//TODO: DMA to be implemented //TODO: DMA to be implemented
_USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_RXC; _USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_RXC;
obj->rx_buff.pos = 0;
obj->rx_buff.length = 0;
} }
#endif #endif