mbed library sources
Fork of mbed-src by
targets/hal/TARGET_Atmel/TARGET_SAM21/TARGET_SAMR21G18A/PeripheralPins.c
- Committer:
- mbed_official
- Date:
- 2015-07-01
- Revision:
- 579:53297373a894
- Child:
- 592:a274ee790e56
File content as of revision 579:53297373a894:
/* mbed Microcontroller Library * Copyright (c) 2006-2013 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #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[] = { }; /************ADC***************/ const PinMap PinMap_ADC[] = { }; /************DAC***************/ const PinMap PinMap_DAC[] = { }; /************I2C***************/ const PinMap PinMap_I2C_SDA[] = { }; const PinMap PinMap_I2C_SCL[] = { }; /************UART***************/ const PinMap PinMap_UART_TX[] = { {PA04, UART_0, 0} }; const PinMap PinMap_UART_RX[] = { {PA05, UART_0, 0} }; /************SPI***************/ const PinMap PinMap_SPI_SCLK[] = { }; const PinMap PinMap_SPI_MOSI[] = { }; const PinMap PinMap_SPI_MISO[] = { }; 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, PinName chipsel) { 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: 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 ((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) && (chipsel_values.pad/*cts pin*/ == 3)) { mux_setting |= SERCOM_USART_CTRLA_TXPO(2); } } return mux_setting; } 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, chipsel_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; 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); 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); if (chipsel_values.pad < 0x04) pad_pinmuxes[chipsel_values.pad] = find_sercom_pinmux(&chipsel_values); }