⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpio.c

📁 针对at91系列的arm的启动代码的编写有一个整体的说明
💻 C
字号:
/* ---------------------------------------------------------------------------- *         ATMEL Microcontroller Software Support  -  ROUSSET  - * ---------------------------------------------------------------------------- * Copyright (c) 2006, Atmel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the disclaimer below in the documentation and/or * other materials provided with the distribution. * * Atmel's name may not be used to endorse or promote products derived from * this software without specific prior written permission. * * DISCLAIMER: 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 * 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. * ---------------------------------------------------------------------------- * File Name           : gpio.c * Object              : * Creation            : ODi Apr 19th 2006 *----------------------------------------------------------------------------- */#include "../include/part.h"#include "../include/main.h"#include "../include/gpio.h"#include "../include/debug.h"#define EINVAL 1 /* Error code returned when the PIN is unknown *//* Write PIO register */static inline void write_pio(unsigned int offset, const unsigned int value){	writel(value, offset + AT91C_BASE_PIOA);}/* Read PIO registers */static inline unsigned int read_pio(volatile unsigned int offset){	return readl(offset + AT91C_BASE_PIOA);}/* Convert Pin Number into PIO controller index */static inline unsigned pin_to_controller(unsigned pin){	return  (pin) / PIO_NB_IO;}/* Convert Pin Number into I/O line index */static inline unsigned pin_to_mask(unsigned pin){	return 1 << ((pin) % PIO_NB_IO);}/*------------------------------------------------------------------------------*//* \fn    pio_set_A_periph							*//* \brief the pin to the "A" internal peripheral role.				*//*------------------------------------------------------------------------------*/static int pio_set_A_periph(unsigned pin, int use_pullup){	unsigned	pio = pin_to_controller(pin);	unsigned	mask = pin_to_mask(pin);	if (pio >= AT91C_NR_PIO)		return -EINVAL;	write_pio(PIO_IDR(pio), mask);	write_pio(use_pullup ? PIO_PPUER(pio) : PIO_PPUDR(pio), mask);	write_pio(PIO_ASR(pio), mask);	write_pio(PIO_PDR(pio), mask);	return 0;}/*------------------------------------------------------------------------------*//* \fn    pio_set_B_periph							*//* \brief mux the pin to the "B" internal peripheral role.			*//*------------------------------------------------------------------------------*/static int pio_set_B_periph(unsigned pin, int use_pullup){	unsigned	pio = pin_to_controller(pin);	unsigned	mask = pin_to_mask(pin);	if (pio >= AT91C_NR_PIO)		return -EINVAL;	write_pio(PIO_IDR(pio), mask);	write_pio((use_pullup ? PIO_PPUER(pio) : PIO_PPUDR(pio)), mask);	write_pio(PIO_BSR(pio), mask);	write_pio(PIO_PDR(pio), mask);	return 0;}/*------------------------------------------------------------------------------*//* \fn    pio_set_gpio_input							*//* \brief mux the pin to the gpio controller (instead of "A" or "B" peripheral),*//*        and configure it for an input.					*//*------------------------------------------------------------------------------*/static int pio_set_gpio_input(unsigned pin, int use_pullup){	unsigned	pio = pin_to_controller(pin);	unsigned	mask = pin_to_mask(pin);	if (pio >= AT91C_NR_PIO)		return -EINVAL;	write_pio(PIO_IDR(pio), mask);	write_pio((use_pullup ? PIO_PPUER(pio) : PIO_PPUDR(pio)), mask);	write_pio(PIO_ODR(pio), mask);	write_pio(PIO_PER(pio), mask);	return 0;}/*------------------------------------------------------------------------------*//* \fn    pio_set_gpio_input							*//* \brief mux the pin to the gpio controller (instead of "A" or "B" peripheral),*//*        and configure it for an output.					*//*------------------------------------------------------------------------------*/static int pio_set_gpio_output(unsigned pin, int value){	unsigned	pio = pin_to_controller(pin);	unsigned	mask = pin_to_mask(pin);	if (pio >= AT91C_NR_PIO)		return -EINVAL;	write_pio(PIO_IDR(pio), mask);	write_pio(PIO_PPUDR(pio), mask);	write_pio((value ? PIO_SODR(pio) : PIO_CODR(pio)), mask);	write_pio(PIO_OER(pio), mask);	write_pio(PIO_PER(pio), mask);	return 0;}/*------------------------------------------------------------------------------*//* \fn    pio_set_deglitch							*//* \brief enable/disable the glitch filter; mostly used with IRQ handling.	*//*------------------------------------------------------------------------------*/static int pio_set_deglitch(unsigned pin, int is_on){	unsigned	pio = pin_to_controller(pin);	unsigned	mask = pin_to_mask(pin);	if (pio >= AT91C_NR_PIO)		return -EINVAL;	write_pio((is_on ? PIO_IFER(pio) : PIO_IFDR(pio)), mask);	return 0;}/*------------------------------------------------------------------------------*//* \fn    pio_set_multi_drive							*//* \brief enable/disable the multi-driver; This is only valid for output and	*//*        allows the output pin to run as an open collector output.		*//*------------------------------------------------------------------------------*/static int pio_set_multi_drive(unsigned pin, int is_on){	unsigned	pio = pin_to_controller(pin);	unsigned	mask = pin_to_mask(pin);	if (pio >= AT91C_NR_PIO)		return -EINVAL;	write_pio((is_on ? PIO_MDER(pio) : PIO_MDDR(pio)), mask);	return 0;}/*------------------------------------------------------------------------------*//* \fn    pio_set_value								*//* \brief assuming the pin is muxed as a gpio output, set its value.		*//*------------------------------------------------------------------------------*/int pio_set_value(unsigned pin, int value){	unsigned	pio = pin_to_controller(pin);	unsigned	mask = pin_to_mask(pin);	if (pio >= AT91C_NR_PIO)		return -EINVAL;	write_pio((value ? PIO_SODR(pio) : PIO_CODR(pio)), mask);	return 0;}/*------------------------------------------------------------------------------*//* \fn    pio_get_value								*//* \brief read the pin's value (works even if it's not muxed as a gpio).	*//*        !!! PIO Clock must be enabled in the PMC !!!				*//*------------------------------------------------------------------------------*/int pio_get_value(unsigned pin){	unsigned	pio = pin_to_controller(pin);	unsigned	mask = pin_to_mask(pin);	unsigned int		pdsr;	if (pio >= AT91C_NR_PIO)		return -EINVAL;	pdsr = read_pio(PIO_PDSR(pio));	return (pdsr & mask) != 0;}/*------------------------------------------------------------------------------*//* \fn    pio_device_pio_setup							*//* \brief Configure PIO in periph mode according to the platform informations	*//*------------------------------------------------------------------------------*/int pio_setup (const struct pio_desc *pio_desc){        unsigned        pio, pin = 0;        if(!pio_desc) {                return 0;        }        /* Sets all the pio muxing of the corresponding device as defined in its platform_data struct */        while (pio_desc->pin_name) {                pio = pin_to_controller( pio_desc->pin_num);                if (pio >= AT91C_NR_PIO)                		return 0;                else if (pio_desc->type == PIO_PERIPH_A)                        pio_set_A_periph(pio_desc->pin_num,                                (pio_desc->attribute & PIO_PULLUP) ? 1 : 0);                else if (pio_desc->type == PIO_PERIPH_B)                        pio_set_B_periph(pio_desc->pin_num,                                (pio_desc->attribute & PIO_PULLUP) ? 1 : 0);                else if (pio_desc->type == PIO_INPUT) {                        pio_set_deglitch(pio_desc->pin_num,                                (pio_desc->attribute & PIO_DEGLITCH)? 1 : 0);                        pio_set_gpio_input(pio_desc->pin_num,                                (pio_desc->attribute & PIO_PULLUP) ? 1 : 0);                }                else if(pio_desc->type == PIO_OUTPUT) {                        pio_set_multi_drive(pio_desc->pin_num, (pio_desc->attribute & PIO_OPENDRAIN) ? 1 : 0);                        pio_set_gpio_output(pio_desc->pin_num, pio_desc->dft_value);                }                else                         return 0;                ++pin;                ++pio_desc;        }        return pin;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -