mirror of https://github.com/ARMmbed/mbed-os.git
* updated functions for hardware flow control apis - not tested.
* updated sercom pin muxing to incorporate hardware flow control.pull/1214/head
parent
a582b9f6a6
commit
f55e6bd54a
|
@ -21,7 +21,7 @@
|
|||
#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
|
||||
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***************/
|
||||
//extern const PinMap PinMap_RTC[];
|
||||
|
||||
|
|
|
@ -425,22 +425,25 @@ uint32_t find_sercom_pinmux (struct pin_values* PinValues)
|
|||
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;
|
||||
|
||||
input_values.pin = input;
|
||||
output_values.pin = output;
|
||||
clock_values.pin = clock;
|
||||
chipsel_values.pin = chipsel;
|
||||
|
||||
input_values.com = pinmap_sercom_peripheral(input, output);
|
||||
output_values.com = input_values.com;
|
||||
clock_values.com = input_values.com;
|
||||
chipsel_values.com = input_values.com;
|
||||
|
||||
input_values.pad = pinmap_sercom_pad(input);
|
||||
output_values.pad = pinmap_sercom_pad(output);
|
||||
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.
|
||||
case 0:
|
||||
|
@ -457,17 +460,21 @@ uint32_t find_mux_setting (PinName output, PinName input, PinName clock)
|
|||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
} else if(/*((output_values.pad == 2) && (clock_values.pad == 3)) ||*/ (output_values.pad == 2)) {
|
||||
mux_setting |= SERCOM_USART_CTRLA_TXPO(1);
|
||||
}
|
||||
/*else if((output_values.pad == 0)) { // condition for hardware enabled
|
||||
mux_setting |= SERCOM_USART_CTRLA_TXPO(2);
|
||||
}*/
|
||||
else {
|
||||
mux_setting = mux_setting; // dummy condition
|
||||
}
|
||||
if ((clock == NC) && (chipsel == NC)) // condition for no hardware control and uart
|
||||
{
|
||||
if ((output_values.pad == 0)) { // condition for hardware enable and usart is different
|
||||
mux_setting |= SERCOM_USART_CTRLA_TXPO(0);
|
||||
} else if((output_values.pad == 2)) {
|
||||
mux_setting |= SERCOM_USART_CTRLA_TXPO(1);
|
||||
} 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;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ struct serial_s {
|
|||
uint32_t pinmux_pad1;
|
||||
uint32_t pinmux_pad2;
|
||||
uint32_t pinmux_pad3;
|
||||
PinName rxpin;
|
||||
PinName txpin;
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
uint32_t events;
|
||||
#endif
|
||||
|
|
|
@ -196,8 +196,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
|
|||
|
||||
get_default_serial_values(obj);
|
||||
|
||||
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
|
||||
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, NC); // getting mux setting from pins
|
||||
sercom_index = pinmap_sercom_peripheral(tx, rx); // same variable sercom_index reused for optimization
|
||||
switch (sercom_index) {
|
||||
case 0:
|
||||
|
@ -226,6 +226,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
|
|||
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)->pinmux_pad0 = padsetting[0];//EDBG_CDC_SERCOM_PINMUX_PAD0;
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef DEVICE_SERIAL_FC
|
||||
|
||||
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
|
||||
******************************************************************************/
|
||||
|
@ -897,6 +958,7 @@ int serial_irq_handler_asynch(serial_t *obj)
|
|||
if(obj->tx_buff.pos >= obj->tx_buff.length) {
|
||||
|
||||
/* Transfer complete. Switch off interrupt and return event. */
|
||||
_USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_DRE;
|
||||
serial_tx_abort_asynch(obj);
|
||||
|
||||
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)
|
||||
{
|
||||
//TODO: DMA to be implemented
|
||||
_USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_DRE;
|
||||
_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
|
||||
* 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
|
||||
_USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_RXC;
|
||||
obj->rx_buff.pos = 0;
|
||||
obj->rx_buff.length = 0;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue