mirror of https://github.com/ARMmbed/mbed-os.git
* Pin mux logic added for sercom
* added support for 6 uarts in code. * updated gpio for output setting * updated device.h for adding async apis for serialpull/1214/head
parent
98d628b67f
commit
a7b2cee60d
|
@ -33,7 +33,12 @@ extern "C" {
|
|||
|
||||
|
||||
typedef enum {
|
||||
UART_0 = (int)0x42000800UL // Base address of SERCOM0
|
||||
UART_0 = (int)0x42000800UL, // Base address of SERCOM0
|
||||
UART_1 = (int)0x42000C00UL, // Base address of SERCOM1
|
||||
UART_2 = (int)0x42001000UL, // Base address of SERCOM2
|
||||
UART_3 = (int)0x42001400UL, // Base address of SERCOM3
|
||||
UART_4 = (int)0x42001800UL, // Base address of SERCOM4
|
||||
UART_5 = (int)0x42001C00UL // Base address of SERCOM5
|
||||
} UARTName;
|
||||
/*
|
||||
typedef enum {
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "pinmap.h"
|
||||
#include "PeripheralNames.h"
|
||||
|
||||
void find_pin_settings (PinName output, PinName input, PinName clock, uint32_t* pad_pinmuxes);
|
||||
uint32_t find_mux_setting (PinName output, PinName input, PinName clock);
|
||||
/************RTC***************/
|
||||
//extern const PinMap PinMap_RTC[];
|
||||
|
||||
|
@ -46,4 +48,6 @@ extern const PinMap PinMap_UART_RX[];
|
|||
/************PWM***************/
|
||||
//extern const PinMap PinMap_PWM[];
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -94,9 +94,13 @@ typedef enum {
|
|||
PB29 = 61,
|
||||
PB30 = 62,
|
||||
PB31 = 63,
|
||||
|
||||
PC16 = 64,
|
||||
PC18 = 65,
|
||||
PC19 = 66,
|
||||
|
||||
USBTX = PA04,
|
||||
USBRX = PA05,
|
||||
USBTX = PA04,
|
||||
USBRX = PA05,
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
|
|
|
@ -16,6 +16,18 @@
|
|||
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
#define SERCOM_NULL 0xFF
|
||||
#define MUX_NULL 0xFF
|
||||
|
||||
#define SERCOM_USART_CTRLA_RXPO_Pos 20 /**< \brief (SERCOM_USART_CTRLA) Receive Data Pinout */
|
||||
#define SERCOM_USART_CTRLA_RXPO_Msk (0x3ul << SERCOM_USART_CTRLA_RXPO_Pos)
|
||||
#define SERCOM_USART_CTRLA_RXPO(value) ((SERCOM_USART_CTRLA_RXPO_Msk & ((value) << SERCOM_USART_CTRLA_RXPO_Pos)))
|
||||
|
||||
#define SERCOM_USART_CTRLA_TXPO_Pos 16 /**< \brief (SERCOM_USART_CTRLA) Transmit Data Pinout */
|
||||
#define SERCOM_USART_CTRLA_TXPO_Msk (0x3ul << SERCOM_USART_CTRLA_TXPO_Pos)
|
||||
#define SERCOM_USART_CTRLA_TXPO(value) ((SERCOM_USART_CTRLA_TXPO_Msk & ((value) << SERCOM_USART_CTRLA_TXPO_Pos)))
|
||||
|
||||
|
||||
/************RTC***************/
|
||||
const PinMap PinMap_RTC[] = {
|
||||
};
|
||||
|
@ -60,3 +72,438 @@ const PinMap PinMap_SPI_SSEL[] = {
|
|||
/************PWM***************/
|
||||
const PinMap PinMap_PWM[] = {
|
||||
};
|
||||
|
||||
/********SERCOM MAPPING*********/
|
||||
struct pin_sercom{
|
||||
uint8_t pad_num; // a pin always mapped to a pad
|
||||
uint8_t com_num[2]; // a pin always mapped to maximum of 2 sercoms
|
||||
// uint8_t pin_mux[2]; // Mux setting for the pin A,B...H ---> 0,1...7
|
||||
};
|
||||
struct pin_values{
|
||||
uint8_t pin;
|
||||
uint8_t pad;
|
||||
uint8_t com;
|
||||
};
|
||||
|
||||
struct pin_sercom SAM21[] = {{0, {1, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PA00
|
||||
{1, {1, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PA01
|
||||
{0, {0, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PA04
|
||||
{1, {0, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PA05
|
||||
{2, {0, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PA06
|
||||
{3, {0, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PA07
|
||||
{0, {0, 2}/*, {2, 3}*/}, // PA08
|
||||
{1, {0, 2}/*, {2, 3}*/}, // PA09
|
||||
{0, {2, SERCOM_NULL}/*, {2, MUX_NULL}*/}, // PA12
|
||||
{1, {2, SERCOM_NULL}/*, {2, MUX_NULL}*/}, // PA13
|
||||
{2, {2, SERCOM_NULL}/*, {2, MUX_NULL}*/}, // PA14
|
||||
{3, {2, SERCOM_NULL}/*, {2, MUX_NULL}*/}, // PA15
|
||||
{0, {1, 3}/*, {2, 3}*/}, // PA16
|
||||
{1, {1, 3}/*, {2, 3}*/}, // PA17
|
||||
{2, {1, 3}/*, {2, 3}*/}, // PA18
|
||||
{3, {1, 3}/*, {2, 3}*/}, // PA19
|
||||
{0, {3, 5}/*, {2, 3}*/}, // PA22
|
||||
{1, {3, 5}/*, {2, 3}*/}, // PA23
|
||||
{2, {3, 5}/*, {2, 3}*/}, // PA24
|
||||
{3, {3, 5}/*, {2, 3}*/}, // PA25
|
||||
{0, {3, SERCOM_NULL}/*, {5, MUX_NULL}*/}, // PA27
|
||||
{1, {3, SERCOM_NULL}/*, {5, MUX_NULL}*/}, // PA28
|
||||
{2, {1, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PA30
|
||||
{3, {1, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PA31
|
||||
{0, {5, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PB02
|
||||
{1, {5, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PB03
|
||||
{2, {5, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PB22
|
||||
{3, {5, SERCOM_NULL}/*, {3, MUX_NULL}*/}, // PB23
|
||||
{2, {4, SERCOM_NULL}/*, {5, MUX_NULL}*/}, // PB30
|
||||
{1, {4, SERCOM_NULL}/*, {5, MUX_NULL}*/}, // PB31
|
||||
{3, {4, SERCOM_NULL}/*, {5, MUX_NULL}*/}, // PC18
|
||||
{0, {4, SERCOM_NULL}/*, {5, MUX_NULL}*/} // PC19
|
||||
};
|
||||
const PinMap PinMap_SERCOM_PINS[] = {
|
||||
{PA00},
|
||||
{PA01},
|
||||
{PA04},
|
||||
{PA05},
|
||||
{PA06},
|
||||
{PA07},
|
||||
{PA08},
|
||||
{PA09},
|
||||
{PA12},
|
||||
{PA13},
|
||||
{PA14},
|
||||
{PA15},
|
||||
{PA16},
|
||||
{PA17},
|
||||
{PA18},
|
||||
{PA19},
|
||||
{PA22},
|
||||
{PA23},
|
||||
{PA24},
|
||||
{PA25},
|
||||
{PA27},
|
||||
{PA28},
|
||||
{PA30},
|
||||
{PA31},
|
||||
|
||||
{PB02},
|
||||
{PB03},
|
||||
{PB22},
|
||||
{PB23},
|
||||
{PB30},
|
||||
{PB31},
|
||||
|
||||
{PC18},
|
||||
{PC19}
|
||||
|
||||
};
|
||||
|
||||
uint32_t pinmap_find_sercom_index (PinName pin, const PinMap* map)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
while (map->pin != NC) {
|
||||
if (map->pin == pin)
|
||||
return count;
|
||||
map++;
|
||||
count++;
|
||||
}
|
||||
return (uint32_t)NC;
|
||||
}
|
||||
|
||||
uint32_t pinmap_sercom_peripheral (PinName pin1, PinName pin2)
|
||||
{
|
||||
uint8_t index1 = 0, index2 = 0;
|
||||
|
||||
if ((pin1 == (PinName)NC) || (pin2 == (PinName)NC)) {
|
||||
return (uint32_t)NC;
|
||||
}
|
||||
|
||||
index1 = pinmap_find_sercom_index(pin1, PinMap_SERCOM_PINS);
|
||||
index2 = pinmap_find_sercom_index(pin2, PinMap_SERCOM_PINS);
|
||||
|
||||
if (SAM21[index1].com_num[1] == SERCOM_NULL) {
|
||||
return SAM21[index1].com_num[0];
|
||||
} else {
|
||||
if ((SAM21[index1].com_num[0] == SAM21[index2].com_num[0]) || (SAM21[index1].com_num[0] == SAM21[index2].com_num[1])) {
|
||||
return SAM21[index1].com_num[0];
|
||||
} else {
|
||||
return SAM21[index1].com_num[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pinmap_sercom_pad (PinName pin)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
|
||||
if (pin == (PinName)NC)
|
||||
return (uint32_t)NC;
|
||||
|
||||
index = pinmap_find_sercom_index(pin, PinMap_SERCOM_PINS);
|
||||
return SAM21[index].pad_num;
|
||||
}
|
||||
|
||||
uint32_t find_sercom_pinmux (struct pin_values* PinValues)
|
||||
{
|
||||
switch (PinValues->com) {
|
||||
case 0: // SERCOM0
|
||||
switch (PinValues->pin) {
|
||||
case PA04:
|
||||
return PINMUX_PA04D_SERCOM0_PAD0;
|
||||
break;
|
||||
case PA08:
|
||||
return PINMUX_PA08C_SERCOM0_PAD0;
|
||||
break;
|
||||
case PA05:
|
||||
return PINMUX_PA05D_SERCOM0_PAD1;
|
||||
break;
|
||||
case PA09:
|
||||
return PINMUX_PA09C_SERCOM0_PAD1;
|
||||
break;
|
||||
case PA06:
|
||||
return PINMUX_PA06D_SERCOM0_PAD2;
|
||||
break;
|
||||
case PA10:
|
||||
return PINMUX_PA10C_SERCOM0_PAD2;
|
||||
break;
|
||||
case PA07:
|
||||
return PINMUX_PA07D_SERCOM0_PAD3;
|
||||
break;
|
||||
case PA11:
|
||||
return PINMUX_PA11C_SERCOM0_PAD3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1: // SERCOM1
|
||||
switch (PinValues->pin) {
|
||||
case PA16:
|
||||
return PINMUX_PA16C_SERCOM1_PAD0;
|
||||
break;
|
||||
case PA00:
|
||||
return PINMUX_PA00D_SERCOM1_PAD0;
|
||||
break;
|
||||
case PA17:
|
||||
return PINMUX_PA17C_SERCOM1_PAD1;
|
||||
break;
|
||||
case PA01:
|
||||
return PINMUX_PA01D_SERCOM1_PAD1;
|
||||
break;
|
||||
case PA30:
|
||||
return PINMUX_PA30D_SERCOM1_PAD2;
|
||||
break;
|
||||
case PA18:
|
||||
return PINMUX_PA18C_SERCOM1_PAD2;
|
||||
break;
|
||||
case PA31:
|
||||
return PINMUX_PA31D_SERCOM1_PAD3;
|
||||
break;
|
||||
case PA19:
|
||||
return PINMUX_PA19C_SERCOM1_PAD3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2: // SERCOM2
|
||||
switch (PinValues->pin) {
|
||||
case PA08:
|
||||
return PINMUX_PA08D_SERCOM2_PAD0;
|
||||
break;
|
||||
case PA12:
|
||||
return PINMUX_PA12C_SERCOM2_PAD0;
|
||||
break;
|
||||
case PA09:
|
||||
return PINMUX_PA09D_SERCOM2_PAD1;
|
||||
break;
|
||||
case PA13:
|
||||
return PINMUX_PA13C_SERCOM2_PAD1;
|
||||
break;
|
||||
case PA10:
|
||||
return PINMUX_PA10D_SERCOM2_PAD2;
|
||||
break;
|
||||
case PA14:
|
||||
return PINMUX_PA14C_SERCOM2_PAD2;
|
||||
break;
|
||||
case PA11:
|
||||
return PINMUX_PA11D_SERCOM2_PAD3;
|
||||
break;
|
||||
case PA15:
|
||||
return PINMUX_PA15C_SERCOM2_PAD3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3: // SERCOM3
|
||||
switch (PinValues->pin) {
|
||||
case PA16:
|
||||
return PINMUX_PA16D_SERCOM3_PAD0;
|
||||
break;
|
||||
case PA22:
|
||||
return PINMUX_PA22C_SERCOM3_PAD0;
|
||||
break;
|
||||
case PA27:
|
||||
return PINMUX_PA27F_SERCOM3_PAD0;
|
||||
break;
|
||||
case PA17:
|
||||
return PINMUX_PA17D_SERCOM3_PAD1;
|
||||
break;
|
||||
case PA23:
|
||||
return PINMUX_PA23C_SERCOM3_PAD1;
|
||||
break;
|
||||
case PA28:
|
||||
return PINMUX_PA28F_SERCOM3_PAD1;
|
||||
break;
|
||||
case PA18:
|
||||
return PINMUX_PA18D_SERCOM3_PAD2;
|
||||
break;
|
||||
case PA20:
|
||||
return PINMUX_PA20D_SERCOM3_PAD2;
|
||||
break;
|
||||
case PA24:
|
||||
return PINMUX_PA24C_SERCOM3_PAD2;
|
||||
break;
|
||||
case PA19:
|
||||
return PINMUX_PA19D_SERCOM3_PAD3;
|
||||
break;
|
||||
case PA25:
|
||||
return PINMUX_PA25C_SERCOM3_PAD3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4: // SERCOM4
|
||||
switch (PinValues->pin) {
|
||||
case PA12:
|
||||
return PINMUX_PA12D_SERCOM4_PAD0;
|
||||
break;
|
||||
case PB08:
|
||||
return PINMUX_PB08D_SERCOM4_PAD0;
|
||||
break;
|
||||
case PC19:
|
||||
return PINMUX_PC19F_SERCOM4_PAD0;
|
||||
break;
|
||||
case PA13:
|
||||
return PINMUX_PA13D_SERCOM4_PAD1;
|
||||
break;
|
||||
case PB09:
|
||||
return PINMUX_PB09D_SERCOM4_PAD1;
|
||||
break;
|
||||
case PB31:
|
||||
return PINMUX_PB31F_SERCOM4_PAD1;
|
||||
break;
|
||||
case PA14:
|
||||
return PINMUX_PA14D_SERCOM4_PAD2;
|
||||
break;
|
||||
case PB14:
|
||||
return PINMUX_PB14C_SERCOM4_PAD2;
|
||||
break;
|
||||
case PB30:
|
||||
return PINMUX_PB30F_SERCOM4_PAD2;
|
||||
break;
|
||||
case PA15:
|
||||
return PINMUX_PA15D_SERCOM4_PAD3;
|
||||
break;
|
||||
case PB15:
|
||||
return PINMUX_PB15C_SERCOM4_PAD3;
|
||||
break;
|
||||
case PC18:
|
||||
return PINMUX_PC18F_SERCOM4_PAD3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 5: // SERCOM5
|
||||
switch (PinValues->pin) {
|
||||
case PB16:
|
||||
return PINMUX_PB16C_SERCOM5_PAD0;
|
||||
break;
|
||||
case PA22:
|
||||
return PINMUX_PA22D_SERCOM5_PAD0;
|
||||
break;
|
||||
case PB02:
|
||||
return PINMUX_PB02D_SERCOM5_PAD0;
|
||||
break;
|
||||
case PB30:
|
||||
return PINMUX_PB30D_SERCOM5_PAD0;
|
||||
break;
|
||||
case PB17:
|
||||
return PINMUX_PB17C_SERCOM5_PAD1;
|
||||
break;
|
||||
case PA23:
|
||||
return PINMUX_PA23D_SERCOM5_PAD1;
|
||||
break;
|
||||
case PB03:
|
||||
return PINMUX_PB03D_SERCOM5_PAD1;
|
||||
break;
|
||||
case PB31:
|
||||
return PINMUX_PB31D_SERCOM5_PAD1;
|
||||
break;
|
||||
case PA24:
|
||||
return PINMUX_PA24D_SERCOM5_PAD2;
|
||||
break;
|
||||
case PB00:
|
||||
return PINMUX_PB00D_SERCOM5_PAD2;
|
||||
break;
|
||||
case PB22:
|
||||
return PINMUX_PB22D_SERCOM5_PAD2;
|
||||
break;
|
||||
case PA20:
|
||||
return PINMUX_PA20C_SERCOM5_PAD2;
|
||||
break;
|
||||
case PA25:
|
||||
return PINMUX_PA25D_SERCOM5_PAD3;
|
||||
break;
|
||||
case PB23:
|
||||
return PINMUX_PB23D_SERCOM5_PAD3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint32_t find_mux_setting (PinName output, PinName input, PinName clock)
|
||||
{
|
||||
struct pin_values input_values, output_values, clock_values;
|
||||
uint32_t mux_setting = 0;
|
||||
|
||||
input_values.pin = input;
|
||||
output_values.pin = output;
|
||||
clock_values.pin = clock;
|
||||
|
||||
input_values.com = pinmap_sercom_peripheral(input, output);
|
||||
output_values.com = input_values.com;
|
||||
clock_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);
|
||||
|
||||
switch(input_values.pad) { //TODO: Condition for hardware flow control enabled is different.
|
||||
case 0:
|
||||
mux_setting |= SERCOM_USART_CTRLA_RXPO(0);
|
||||
break;
|
||||
case 1:
|
||||
mux_setting |= SERCOM_USART_CTRLA_RXPO(1);
|
||||
break;
|
||||
case 2:
|
||||
mux_setting |= SERCOM_USART_CTRLA_RXPO(2);
|
||||
break;
|
||||
case 3:
|
||||
mux_setting |= SERCOM_USART_CTRLA_RXPO(3);
|
||||
break;
|
||||
}
|
||||
|
||||
if (((output_values.pad == 0) && (clock_values.pad == 1)) || (output_values.pad == 0)) {
|
||||
mux_setting |= SERCOM_USART_CTRLA_TXPO(0);
|
||||
}
|
||||
else if((output_values.pad == 2) && (clock_values.pad == 3)) {
|
||||
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
|
||||
}
|
||||
|
||||
return mux_setting;
|
||||
}
|
||||
|
||||
void find_pin_settings (PinName output, PinName input, PinName clock, uint32_t* pad_pinmuxes)
|
||||
{
|
||||
struct pin_values input_values, output_values, clock_values;
|
||||
uint8_t i = 0;
|
||||
|
||||
for (i = 0; i < 4 ; i++ ){ // load default values for the pins
|
||||
pad_pinmuxes[i] = 0xFFFFFFFF; //PINMUX_UNUSED
|
||||
}
|
||||
|
||||
input_values.pin = input;
|
||||
output_values.pin = output;
|
||||
clock_values.pin = clock;
|
||||
|
||||
input_values.com = pinmap_sercom_peripheral(input, output);
|
||||
output_values.com = input_values.com;
|
||||
clock_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);
|
||||
|
||||
if (input_values.pad < 0x04)
|
||||
pad_pinmuxes[input_values.pad] = find_sercom_pinmux(&input_values);
|
||||
if (output_values.pad < 0x04)
|
||||
pad_pinmuxes[output_values.pad] = find_sercom_pinmux(&output_values);
|
||||
if (clock_values.pad < 0x04)
|
||||
pad_pinmuxes[clock_values.pad] = find_sercom_pinmux(&clock_values);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#define DEVICE_SERIAL 1
|
||||
#define DEVICE_SERIAL_FC 1
|
||||
#define DEVICE_SERIAL_ASYNCH 1
|
||||
|
||||
#define DEVICE_I2C 0
|
||||
#define DEVICE_I2CSLAVE 0
|
||||
|
|
|
@ -79,7 +79,7 @@ void gpio_dir(gpio_t *obj, PinDirection direction) {
|
|||
pin_conf.direction = PORT_PIN_DIR_INPUT;
|
||||
break;
|
||||
case PIN_OUTPUT:
|
||||
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
|
||||
pin_conf.direction = /*PORT_PIN_DIR_OUTPUT*/PORT_PIN_DIR_OUTPUT_WTH_READBACK;
|
||||
break;
|
||||
case PIN_INPUT_OUTPUT:
|
||||
pin_conf.direction = PORT_PIN_DIR_OUTPUT_WTH_READBACK;
|
||||
|
|
|
@ -22,9 +22,18 @@
|
|||
#include "usart.h"
|
||||
#include "samr21_xplained_pro.h"
|
||||
|
||||
#define _USART(obj) obj->usart->USART
|
||||
#define USART_NUM 1 // for SAMR21 // to be updated for samd21
|
||||
//#define USART_BUF 8
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
#define pUSART_S(obj) obj->serial.usart
|
||||
#define pSERIAL_S(obj) ((struct serial_s*)&(obj->serial))
|
||||
#else
|
||||
#define pUSART_S(obj) obj->serial
|
||||
#define pSERIAL_S(obj) ((struct serial_s*)obj)
|
||||
#endif
|
||||
#define _USART(obj) pUSART_S(obj)->USART
|
||||
#define USART_NUM 6
|
||||
|
||||
|
||||
uint8_t serial_get_index(serial_t *obj);
|
||||
|
||||
static uint32_t serial_irq_ids[USART_NUM] = {0};
|
||||
static uart_irq_handler irq_handler;
|
||||
|
@ -32,13 +41,6 @@ static uart_irq_handler irq_handler;
|
|||
int stdio_uart_inited = 0;
|
||||
serial_t stdio_uart;
|
||||
|
||||
|
||||
/*struct serial_global_data_s{
|
||||
uint8_t string[USART_BUF];
|
||||
uint8_t count;
|
||||
};
|
||||
static struct serial_global_data_s uart_data[USART_NUM];*/
|
||||
|
||||
extern uint8_t g_sys_init;
|
||||
|
||||
static inline bool usart_syncing(serial_t *obj)
|
||||
|
@ -56,7 +58,7 @@ static inline void enable_usart(serial_t *obj)
|
|||
|
||||
#if USART_CALLBACK_MODE == true //TODO: to be implemented
|
||||
/* Enable Global interrupt for module */
|
||||
system_interrupt_enable(_sercom_get_interrupt_vector(obj->usart));
|
||||
// system_interrupt_enable(_sercom_get_interrupt_vector(pUSART_S(obj))); // not required in implementation
|
||||
#endif
|
||||
|
||||
/* Wait until synchronization is complete */
|
||||
|
@ -73,7 +75,7 @@ static inline void disable_usart(serial_t *obj)
|
|||
|
||||
#if USART_CALLBACK_MODE == true //TODO: to be implemented
|
||||
/* Disable Global interrupt for module */
|
||||
system_interrupt_disable(_sercom_get_interrupt_vector(obj->usart));
|
||||
// system_interrupt_disable(_sercom_get_interrupt_vector(pUSART_S(obj))); // not required in implementation
|
||||
#endif
|
||||
/* Wait until synchronization is complete */
|
||||
usart_syncing(obj);
|
||||
|
@ -100,7 +102,7 @@ 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 sercom_index = _sercom_get_sercom_inst_index(pUSART_S(obj));
|
||||
uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
|
||||
|
||||
/* Cache new register values to minimize the number of register writes */
|
||||
|
@ -112,31 +114,31 @@ static enum status_code usart_set_config_asf( serial_t *obj)
|
|||
enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
|
||||
|
||||
/* Set data order, internal muxing, and clock polarity */
|
||||
ctrla = (uint32_t)obj->data_order |
|
||||
(uint32_t)obj->mux_setting |
|
||||
ctrla = (uint32_t)pSERIAL_S(obj)->data_order |
|
||||
(uint32_t)pSERIAL_S(obj)->mux_setting |
|
||||
#ifdef FEATURE_USART_OVER_SAMPLE
|
||||
obj->sample_adjustment |
|
||||
obj->sample_rate |
|
||||
pSERIAL_S(obj)->sample_adjustment |
|
||||
pSERIAL_S(obj)->sample_rate |
|
||||
#endif
|
||||
(obj->clock_polarity_inverted << SERCOM_USART_CTRLA_CPOL_Pos);
|
||||
(pSERIAL_S(obj)->clock_polarity_inverted << SERCOM_USART_CTRLA_CPOL_Pos);
|
||||
|
||||
/* Get baud value from mode and clock */
|
||||
switch (obj->transfer_mode)
|
||||
switch (pSERIAL_S(obj)->transfer_mode)
|
||||
{
|
||||
case USART_TRANSFER_SYNCHRONOUSLY:
|
||||
if (!obj->use_external_clock) {
|
||||
_sercom_get_sync_baud_val(obj->baudrate,
|
||||
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 (obj->use_external_clock) {
|
||||
_sercom_get_async_baud_val(obj->baudrate,
|
||||
obj->ext_clock_freq, &baud, mode, sample_num);
|
||||
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(obj->baudrate,
|
||||
_sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate,
|
||||
system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
|
||||
}
|
||||
|
||||
|
@ -150,9 +152,9 @@ static enum status_code usart_set_config_asf( serial_t *obj)
|
|||
_USART(obj).BAUD.reg = baud;
|
||||
|
||||
/* Set sample mode */
|
||||
ctrla |= obj->transfer_mode;
|
||||
ctrla |= pSERIAL_S(obj)->transfer_mode;
|
||||
|
||||
if (obj->use_external_clock == false) {
|
||||
if (pSERIAL_S(obj)->use_external_clock == false) {
|
||||
ctrla |= SERCOM_USART_CTRLA_MODE(0x1);
|
||||
}
|
||||
else {
|
||||
|
@ -160,23 +162,23 @@ static enum status_code usart_set_config_asf( serial_t *obj)
|
|||
}
|
||||
|
||||
/* Set stopbits, character size and enable transceivers */
|
||||
ctrlb = (uint32_t)obj->stopbits | (uint32_t)obj->character_size |
|
||||
ctrlb = (uint32_t)pSERIAL_S(obj)->stopbits | (uint32_t)pSERIAL_S(obj)->character_size |
|
||||
#ifdef FEATURE_USART_START_FRAME_DECTION
|
||||
(obj->start_frame_detection_enable << SERCOM_USART_CTRLB_SFDE_Pos) |
|
||||
(pSERIAL_S(obj)->start_frame_detection_enable << SERCOM_USART_CTRLB_SFDE_Pos) |
|
||||
#endif
|
||||
(obj->receiver_enable << SERCOM_USART_CTRLB_RXEN_Pos) |
|
||||
(obj->transmitter_enable << SERCOM_USART_CTRLB_TXEN_Pos);
|
||||
(pSERIAL_S(obj)->receiver_enable << SERCOM_USART_CTRLB_RXEN_Pos) |
|
||||
(pSERIAL_S(obj)->transmitter_enable << SERCOM_USART_CTRLB_TXEN_Pos);
|
||||
|
||||
/* Check parity mode bits */
|
||||
if (obj->parity != USART_PARITY_NONE) {
|
||||
if (pSERIAL_S(obj)->parity != USART_PARITY_NONE) {
|
||||
ctrla |= SERCOM_USART_CTRLA_FORM(1);
|
||||
ctrlb |= obj->parity;
|
||||
ctrlb |= pSERIAL_S(obj)->parity;
|
||||
} else {
|
||||
ctrla |= SERCOM_USART_CTRLA_FORM(0);
|
||||
}
|
||||
|
||||
/* Set whether module should run in standby. */
|
||||
if (obj->run_in_standby || system_is_debugger_present()) {
|
||||
if (pSERIAL_S(obj)->run_in_standby || system_is_debugger_present()) {
|
||||
ctrla |= SERCOM_USART_CTRLA_RUNSTDBY;
|
||||
}
|
||||
|
||||
|
@ -195,6 +197,30 @@ static enum status_code usart_set_config_asf( serial_t *obj)
|
|||
return STATUS_OK;
|
||||
}
|
||||
|
||||
void get_default_serial_values(serial_t *obj){
|
||||
/* 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)->stopbits = USART_STOPBITS_1;
|
||||
pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_8BIT;
|
||||
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)->run_in_standby = false;
|
||||
pSERIAL_S(obj)->generator_source = GCLK_GENERATOR_0;
|
||||
pSERIAL_S(obj)->pinmux_pad0 = PINMUX_DEFAULT;
|
||||
pSERIAL_S(obj)->pinmux_pad1 = PINMUX_DEFAULT;
|
||||
pSERIAL_S(obj)->pinmux_pad2 = PINMUX_DEFAULT;
|
||||
pSERIAL_S(obj)->pinmux_pad3 = PINMUX_DEFAULT;
|
||||
pSERIAL_S(obj)->start_frame_detection_enable = false;
|
||||
};
|
||||
|
||||
|
||||
void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
||||
if (g_sys_init == 0) {
|
||||
system_init();
|
||||
|
@ -202,49 +228,51 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
}
|
||||
|
||||
struct system_gclk_chan_config gclk_chan_conf;
|
||||
UARTName uart;
|
||||
uint32_t gclk_index;
|
||||
uint32_t pm_index;
|
||||
uint32_t sercom_index = 0;
|
||||
|
||||
obj->usart = EXT1_UART_MODULE;
|
||||
uint32_t muxsetting = 0;
|
||||
uint32_t padsetting[4] = {0};
|
||||
|
||||
pUSART_S(obj) = EXT1_UART_MODULE;
|
||||
|
||||
/* Disable USART module */
|
||||
disable_usart(obj);
|
||||
|
||||
/* Set default config to object */
|
||||
obj->data_order = USART_DATAORDER_LSB;
|
||||
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;
|
||||
get_default_serial_values(obj);
|
||||
|
||||
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
|
||||
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
|
||||
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
|
||||
UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
|
||||
|
||||
sercom_index = _sercom_get_sercom_inst_index(obj->usart);
|
||||
find_pin_settings(tx, rx, NC, &padsetting[0]); // tx, rx, clk, pad array // getting pads 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
|
||||
switch (sercom_index){
|
||||
case 0:
|
||||
uart = UART_0;
|
||||
break;
|
||||
case 1:
|
||||
uart = UART_1;
|
||||
break;
|
||||
case 2:
|
||||
uart = UART_2;
|
||||
break;
|
||||
case 3:
|
||||
uart = UART_3;
|
||||
break;
|
||||
case 4:
|
||||
uart = UART_4;
|
||||
break;
|
||||
case 5:
|
||||
uart = UART_5;
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
sercom_index = _sercom_get_sercom_inst_index(pUSART_S(obj));
|
||||
pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos;
|
||||
gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
|
||||
|
||||
|
@ -260,11 +288,11 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
|
||||
|
||||
/* Set up the GCLK for the module */
|
||||
obj->generator_source = GCLK_GENERATOR_0;
|
||||
gclk_chan_conf.source_generator = obj->generator_source;
|
||||
pSERIAL_S(obj)->generator_source = 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_enable(gclk_index);
|
||||
sercom_set_gclk_generator(obj->generator_source, false);
|
||||
sercom_set_gclk_generator(pSERIAL_S(obj)->generator_source, false);
|
||||
|
||||
/* Set configuration according to the config struct */
|
||||
usart_set_config_asf(obj);
|
||||
|
@ -274,8 +302,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
|
||||
|
||||
uint32_t pad_pinmuxes[] = {
|
||||
obj->pinmux_pad0, obj->pinmux_pad1,
|
||||
obj->pinmux_pad2, obj->pinmux_pad3
|
||||
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 */
|
||||
|
@ -283,7 +311,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
uint32_t current_pinmux = pad_pinmuxes[pad];
|
||||
|
||||
if (current_pinmux == PINMUX_DEFAULT) {
|
||||
current_pinmux = _sercom_get_default_pad(obj->usart, pad);
|
||||
current_pinmux = _sercom_get_default_pad(pUSART_S(obj), pad);
|
||||
}
|
||||
|
||||
if (current_pinmux != PINMUX_UNUSED) {
|
||||
|
@ -306,7 +334,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
}
|
||||
|
||||
void serial_free(serial_t *obj) {
|
||||
serial_irq_ids[obj->index] = 0;
|
||||
serial_irq_ids[serial_get_index(obj)] = 0;
|
||||
}
|
||||
|
||||
void serial_baud(serial_t *obj, int baudrate) {
|
||||
|
@ -321,34 +349,34 @@ void serial_baud(serial_t *obj, int baudrate) {
|
|||
enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
|
||||
enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
|
||||
|
||||
obj->baudrate = baudrate;
|
||||
pSERIAL_S(obj)->baudrate = baudrate;
|
||||
disable_usart(obj);
|
||||
|
||||
sercom_index = _sercom_get_sercom_inst_index(obj->usart);
|
||||
sercom_index = _sercom_get_sercom_inst_index(pUSART_S(obj));
|
||||
gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
|
||||
|
||||
obj->generator_source = GCLK_GENERATOR_0;
|
||||
gclk_chan_conf.source_generator = obj->generator_source;
|
||||
pSERIAL_S(obj)->generator_source = 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_enable(gclk_index);
|
||||
sercom_set_gclk_generator(obj->generator_source, false);
|
||||
sercom_set_gclk_generator(pSERIAL_S(obj)->generator_source, false);
|
||||
|
||||
/* Get baud value from mode and clock */
|
||||
switch (obj->transfer_mode)
|
||||
switch (pSERIAL_S(obj)->transfer_mode)
|
||||
{
|
||||
case USART_TRANSFER_SYNCHRONOUSLY:
|
||||
if (!obj->use_external_clock) {
|
||||
_sercom_get_sync_baud_val(obj->baudrate,
|
||||
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 (obj->use_external_clock) {
|
||||
_sercom_get_async_baud_val(obj->baudrate,
|
||||
obj->ext_clock_freq, &baud, mode, sample_num);
|
||||
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(obj->baudrate,
|
||||
_sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate,
|
||||
system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
|
||||
}
|
||||
break;
|
||||
|
@ -385,57 +413,54 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
|
||||
switch (stop_bits){
|
||||
case 1:
|
||||
obj->stopbits = USART_STOPBITS_1;
|
||||
pSERIAL_S(obj)->stopbits = USART_STOPBITS_1;
|
||||
break;
|
||||
case 2:
|
||||
obj->stopbits = USART_STOPBITS_2;
|
||||
pSERIAL_S(obj)->stopbits = USART_STOPBITS_2;
|
||||
break;
|
||||
default:
|
||||
obj->stopbits = USART_STOPBITS_1;
|
||||
pSERIAL_S(obj)->stopbits = USART_STOPBITS_1;
|
||||
}
|
||||
|
||||
switch (parity){
|
||||
case ParityNone:
|
||||
obj->parity = USART_PARITY_NONE;
|
||||
pSERIAL_S(obj)->parity = USART_PARITY_NONE;
|
||||
break;
|
||||
case ParityOdd:
|
||||
obj->parity = USART_PARITY_ODD;
|
||||
pSERIAL_S(obj)->parity = USART_PARITY_ODD;
|
||||
break;
|
||||
case ParityEven:
|
||||
obj->parity = USART_PARITY_EVEN;
|
||||
pSERIAL_S(obj)->parity = USART_PARITY_EVEN;
|
||||
break;
|
||||
default:
|
||||
obj->parity = USART_PARITY_NONE;
|
||||
pSERIAL_S(obj)->parity = USART_PARITY_NONE;
|
||||
}
|
||||
|
||||
switch (data_bits){
|
||||
case 5:
|
||||
obj->character_size = USART_CHARACTER_SIZE_5BIT;
|
||||
pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_5BIT;
|
||||
break;
|
||||
case 6:
|
||||
obj->character_size = USART_CHARACTER_SIZE_6BIT;
|
||||
pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_6BIT;
|
||||
break;
|
||||
case 7:
|
||||
obj->character_size = USART_CHARACTER_SIZE_7BIT;
|
||||
pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_7BIT;
|
||||
break;
|
||||
case 8:
|
||||
obj->character_size = USART_CHARACTER_SIZE_8BIT;
|
||||
break;
|
||||
/*case 9:
|
||||
obj->character_size = USART_CHARACTER_SIZE_9BIT;
|
||||
break;*/
|
||||
pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_8BIT;
|
||||
break; // 9 bit transfer not required in mbed
|
||||
default:
|
||||
obj->character_size = USART_CHARACTER_SIZE_8BIT;
|
||||
pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_8BIT;
|
||||
}
|
||||
|
||||
|
||||
/* Set stopbits, character size and enable transceivers */
|
||||
ctrlb = (uint32_t)obj->stopbits | (uint32_t)obj->character_size;
|
||||
ctrlb = (uint32_t)pSERIAL_S(obj)->stopbits | (uint32_t)pSERIAL_S(obj)->character_size;
|
||||
|
||||
/* Check parity mode bits */
|
||||
if (obj->parity != USART_PARITY_NONE) {
|
||||
if (pSERIAL_S(obj)->parity != USART_PARITY_NONE) {
|
||||
ctrla |= SERCOM_USART_CTRLA_FORM(1);
|
||||
ctrlb |= obj->parity;
|
||||
ctrlb |= pSERIAL_S(obj)->parity;
|
||||
} else {
|
||||
ctrla |= SERCOM_USART_CTRLA_FORM(0);
|
||||
}
|
||||
|
@ -458,14 +483,38 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
/******************************************************************************
|
||||
* INTERRUPTS HANDLING
|
||||
******************************************************************************/
|
||||
/**
|
||||
* Get index of serial object, relating it to the physical peripheral.
|
||||
*
|
||||
* @param obj pointer to serial object
|
||||
* @return internal index of U(S)ART peripheral
|
||||
*/
|
||||
inline uint8_t serial_get_index(serial_t *obj)
|
||||
{
|
||||
switch ((int)pSERIAL_S(obj)) {
|
||||
case UART_0:
|
||||
return 0;
|
||||
case UART_1:
|
||||
return 1;
|
||||
case UART_2:
|
||||
return 2;
|
||||
case UART_3:
|
||||
return 3;
|
||||
case UART_4:
|
||||
return 4;
|
||||
case UART_5:
|
||||
return 5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static inline void uart_irq(SercomUsart *const usart, uint32_t index) {
|
||||
uint16_t interrupt_status;
|
||||
interrupt_status = usart->INTFLAG.reg;
|
||||
interrupt_status &= usart->INTENSET.reg;
|
||||
if (serial_irq_ids[index] != 0) {
|
||||
if (interrupt_status & SERCOM_USART_INTFLAG_TXC) // for transmit complete
|
||||
if (interrupt_status & SERCOM_USART_INTFLAG_TXC) // for transmit complete
|
||||
{
|
||||
usart->INTENCLR.reg = SERCOM_USART_INTFLAG_TXC;
|
||||
usart->INTENCLR.reg = SERCOM_USART_INTFLAG_TXC;
|
||||
irq_handler(serial_irq_ids[index], TxIrq);
|
||||
}
|
||||
/*if (interrupt_status & SERCOM_USART_INTFLAG_DRE) // for data ready for transmit
|
||||
|
@ -493,15 +542,29 @@ void uart0_irq() {
|
|||
uart_irq((SercomUsart *)UART_0, 0);
|
||||
}
|
||||
|
||||
/*#if UART_NUM > 1
|
||||
void uart1_irq() {uart_irq(UART1->S1, 1);}
|
||||
void uart2_irq() {uart_irq(UART2->S1, 2);}
|
||||
#endif
|
||||
*/
|
||||
void uart1_irq() {
|
||||
uart_irq((SercomUsart *)UART_1, 0);
|
||||
}
|
||||
|
||||
void uart2_irq() {
|
||||
uart_irq((SercomUsart *)UART_2, 0);
|
||||
}
|
||||
|
||||
void uart3_irq() {
|
||||
uart_irq((SercomUsart *)UART_3, 0);
|
||||
}
|
||||
|
||||
void uart4_irq() {
|
||||
uart_irq((SercomUsart *)UART_4, 0);
|
||||
}
|
||||
|
||||
void uart5_irq() {
|
||||
uart_irq((SercomUsart *)UART_5, 0);
|
||||
}
|
||||
|
||||
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
|
||||
irq_handler = handler;
|
||||
serial_irq_ids[obj->index] = id;
|
||||
serial_irq_ids[serial_get_index(obj)] = id;
|
||||
}
|
||||
|
||||
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
|
||||
|
@ -512,11 +575,31 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
|
|||
disable_usart(obj);
|
||||
ctrlb = _USART(obj).CTRLB.reg;
|
||||
|
||||
switch ((int)obj->usart) {
|
||||
switch ((int)pUSART_S(obj)) {
|
||||
case UART_0:
|
||||
irq_n = SERCOM0_IRQn;
|
||||
vector = (uint32_t)&uart0_irq;
|
||||
break;
|
||||
irq_n = SERCOM0_IRQn;
|
||||
vector = (uint32_t)&uart0_irq;
|
||||
break;
|
||||
case UART_1:
|
||||
irq_n = SERCOM1_IRQn;
|
||||
vector = (uint32_t)&uart1_irq;
|
||||
break;
|
||||
case UART_2:
|
||||
irq_n = SERCOM2_IRQn;
|
||||
vector = (uint32_t)&uart2_irq;
|
||||
break;
|
||||
case UART_3:
|
||||
irq_n = SERCOM3_IRQn;
|
||||
vector = (uint32_t)&uart3_irq;
|
||||
break;
|
||||
case UART_4:
|
||||
irq_n = SERCOM4_IRQn;
|
||||
vector = (uint32_t)&uart4_irq;
|
||||
break;
|
||||
case UART_5:
|
||||
irq_n = SERCOM5_IRQn;
|
||||
vector = (uint32_t)&uart5_irq;
|
||||
break;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
|
@ -559,9 +642,6 @@ int serial_getc(serial_t *obj) {
|
|||
void serial_putc(serial_t *obj, int c) {
|
||||
uint16_t q = (c & SERCOM_USART_DATA_MASK);
|
||||
while (!serial_writable(obj));
|
||||
// uart_data[obj->index].count++;
|
||||
// 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
|
||||
}
|
||||
|
@ -627,7 +707,16 @@ void serial_rx_enable_event(serial_t *obj, int event, uint8_t enable)
|
|||
*/
|
||||
void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t width)
|
||||
{
|
||||
// We only support byte buffers for now
|
||||
MBED_ASSERT(width == 8);
|
||||
|
||||
if(serial_tx_active(obj)) return;
|
||||
|
||||
obj->tx_buff.buffer = tx;
|
||||
obj->tx_buff.length = tx_length;
|
||||
obj->tx_buff.pos = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Configure the TX buffer for an asynchronous read serial transaction
|
||||
|
@ -638,7 +727,16 @@ void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t width)
|
|||
*/
|
||||
void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t width)
|
||||
{
|
||||
// We only support byte buffers for now
|
||||
MBED_ASSERT(width == 8);
|
||||
|
||||
if(serial_rx_active(obj)) return;
|
||||
|
||||
obj->rx_buff.buffer = rx;
|
||||
obj->rx_buff.length = rx_length;
|
||||
obj->rx_buff.pos = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Set character to be matched. If an event is enabled, and received character
|
||||
|
|
Loading…
Reference in New Issue