kopia lustrzana https://github.com/bristol-seds/pico-tracker
223 wiersze
8.0 KiB
C
223 wiersze
8.0 KiB
C
/**
|
|
* SAM D20/D21/R21 Pin Multiplexer Driver
|
|
*
|
|
* Copyright (C) 2012-2014 Atmel Corporation. All rights reserved.
|
|
*
|
|
* \asf_license_start
|
|
*
|
|
* \page License
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* 4. This software may only be redistributed and used in connection with an
|
|
* Atmel microcontroller product.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* \asf_license_stop
|
|
*
|
|
*/
|
|
#ifndef PINMUX_H_INCLUDED
|
|
#define PINMUX_H_INCLUDED
|
|
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include "samd20.h"
|
|
|
|
/*
|
|
* This driver for SAM D20/D21/R21 devices provides an interface for
|
|
* the configuration and management of the device's physical I/O Pins,
|
|
* to alter the direction and input/drive characteristics as well as
|
|
* to configure the pin peripheral multiplexer selection.
|
|
*
|
|
* The following peripherals are used by this module:
|
|
*
|
|
* - PORT (Port I/O Management)
|
|
*
|
|
* Module Overview
|
|
*
|
|
* The SAM D20/D21/R21 devices contain a number of General Purpose I/O
|
|
* pins, used to interface the user application logic and internal
|
|
* hardware peripherals to an external system. The Pin Multiplexer
|
|
* (PINMUX) driver provides a method of configuring the individual pin
|
|
* peripheral multiplexers to select alternate pin functions.
|
|
*
|
|
* Physical and Logical GPIO Pins
|
|
*
|
|
* SAM D20/D21/R21 devices use two naming conventions for the I/O pins
|
|
* in the device; one physical, and one logical. Each physical pin on
|
|
* a device package is assigned both a physical port and pin
|
|
* identifier (e.g. "PORTA.0") as well as a monotonically incrementing
|
|
* logical GPIO number (e.g. "GPIO0"). While the former is used to map
|
|
* physical pins to their physical internal device module
|
|
* counterparts, for simplicity the design of this driver uses the
|
|
* logical GPIO numbers instead.
|
|
*
|
|
* Peripheral Multiplexing
|
|
*
|
|
* SAM D20/D21/R21 devices contain a peripheral MUX, which is
|
|
* individually controllable for each I/O pin of the device. The
|
|
* peripheral MUX allows you to select the function of a physical
|
|
* package pin - whether it will be controlled as a user controllable
|
|
* GPIO pin, or whether it will be connected internally to one of
|
|
* several peripheral modules (such as an I<SUP>2</SUP>C module). When
|
|
* a pin is configured in GPIO mode, other peripherals connected to
|
|
* the same pin will be disabled.
|
|
*
|
|
* Special Pad Characteristics
|
|
*
|
|
* There are several special modes that can be selected on one or more
|
|
* I/O pins of the device, which alter the input and output
|
|
* characteristics of the pad:
|
|
*
|
|
* Drive Strength
|
|
*
|
|
* The Drive Strength configures the strength of the output driver on
|
|
* the pad. Normally, there is a fixed current limit that each I/O pin
|
|
* can safely drive, however some I/O pads offer a higher drive mode
|
|
* which increases this limit for that I/O pin at the expense of an
|
|
* increased power.
|
|
*
|
|
* Slew Rate
|
|
*
|
|
* The Slew Rate configures the slew rate of the output driver,
|
|
* limiting the rate at which the pad output voltage can change with
|
|
* time.
|
|
*
|
|
* Input Sample Mode
|
|
*
|
|
* The Input Sample Mode configures the input sampler buffer of the
|
|
* pad. By default, the input buffer is only sampled "on-demand",
|
|
* i.e. when the user application attempts to read from the input
|
|
* buffer. This mode is the most power efficient, but increases the
|
|
* latency of the input sample by two clock cycles of the port
|
|
* clock. To reduce latency, the input sampler can instead be
|
|
* configured to always sample the input buffer on each port clock
|
|
* cycle, at the expense of an increased power consumption.
|
|
*
|
|
* Special Considerations
|
|
*
|
|
* The SAM D20/D21/R21 port pin input sampling mode is set in groups
|
|
* of four physical pins; setting the sampling mode of any pin in a
|
|
* sub-group of eight I/O pins will configure the sampling mode of the
|
|
* entire sub-group.
|
|
*
|
|
* High Drive Strength output driver mode is not available on all device pins -
|
|
* refer to your device specific datasheet.
|
|
*/
|
|
|
|
/** Peripheral multiplexer index to select GPIO mode for a pin. */
|
|
#define SYSTEM_PINMUX_GPIO (1 << 7)
|
|
|
|
/**
|
|
* Enum for the possible pin direction settings of the port pin configuration
|
|
* structure, to indicate the direction the pin should use.
|
|
*/
|
|
enum system_pinmux_pin_dir {
|
|
/** The pin's input buffer should be enabled, so that the pin state can
|
|
* be read. */
|
|
SYSTEM_PINMUX_PIN_DIR_INPUT,
|
|
|
|
/** The pin's output buffer should be enabled, so that the pin state can
|
|
* be set (but not read back). */
|
|
SYSTEM_PINMUX_PIN_DIR_OUTPUT,
|
|
|
|
/** The pin's output and input buffers should both be enabled, so that the
|
|
* pin state can be set and read back. */
|
|
SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK,
|
|
};
|
|
|
|
/**
|
|
* Enum for the possible pin pull settings of the port pin
|
|
* configuration structure, to indicate the type of logic level pull
|
|
* the pin should use.
|
|
*/
|
|
enum system_pinmux_pin_pull {
|
|
/** No logical pull should be applied to the pin. */
|
|
SYSTEM_PINMUX_PIN_PULL_NONE,
|
|
|
|
/** Pin should be pulled up when idle. */
|
|
SYSTEM_PINMUX_PIN_PULL_UP,
|
|
|
|
/** Pin should be pulled down when idle. */
|
|
SYSTEM_PINMUX_PIN_PULL_DOWN,
|
|
};
|
|
|
|
/**
|
|
* Enum for the possible input sampling modes for the port pin
|
|
* configuration structure, to indicate the type of sampling a port
|
|
* pin should use.
|
|
*/
|
|
enum system_pinmux_pin_sample {
|
|
/** Pin input buffer should continuously sample the pin state. */
|
|
SYSTEM_PINMUX_PIN_SAMPLE_CONTINUOUS,
|
|
|
|
/** Pin input buffer should be enabled when the IN register is read. */
|
|
SYSTEM_PINMUX_PIN_SAMPLE_ONDEMAND,
|
|
};
|
|
|
|
void system_pinmux_pin_set_config(const uint8_t gpio_pin,
|
|
const uint8_t mux_position,
|
|
const enum system_pinmux_pin_dir direction,
|
|
const enum system_pinmux_pin_pull input_pull,
|
|
bool powersave);
|
|
void system_pinmux_group_set_config(PortGroup *const port,
|
|
const uint32_t mask,
|
|
const uint8_t mux_position,
|
|
const enum system_pinmux_pin_dir direction,
|
|
const enum system_pinmux_pin_pull input_pull,
|
|
bool powersave);
|
|
|
|
/**
|
|
* Retrieves the PORT module group instance associated with a given
|
|
* logical GPIO pin number.
|
|
*
|
|
* \param[in] gpio_pin Index of the GPIO pin to convert.
|
|
*
|
|
* \return Base address of the associated PORT module.
|
|
*/
|
|
static inline PortGroup* system_pinmux_get_group_from_gpio_pin(
|
|
const uint8_t gpio_pin)
|
|
{
|
|
uint8_t port_index = (gpio_pin / 128);
|
|
uint8_t group_index = (gpio_pin / 32);
|
|
|
|
/* Array of available ports. */
|
|
Port *const ports[PORT_INST_NUM] = PORT_INSTS;
|
|
|
|
if (port_index < PORT_INST_NUM) {
|
|
return &(ports[port_index]->Group[group_index]);
|
|
} else {
|
|
assert(false);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void system_pinmux_group_set_input_sample_mode(PortGroup *const port,
|
|
const uint32_t mask,
|
|
const enum system_pinmux_pin_sample mode);
|
|
|
|
#endif
|