gpio.c 5.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
/*
 * File      : gpio.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2015, RT-Thread Development Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2015-01-05     Bernard      the first version
 */

#include <rthw.h>
#include <rtdevice.h>
#include <board.h>

#ifdef RT_USING_PIN

/* STM32 GPIO driver */
struct pin_index
{
    int index;
    uint32_t rcc;
    GPIO_TypeDef *gpio;
    uint32_t pin;
};

static const struct pin_index pins[] =
{
    { 0, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_7},
    { 1, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_6},
    { 2, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_8},
    { 3, RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_11},
    { 4, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_14},
    { 5, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_13},
    { 6, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_11},
    { 7, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_9},

    { 8, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_12},
    { 9, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_13},
    {10, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_14},
    {11, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_15},
    {12, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_6},
    {13, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_5},

    {14, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_8},
    {15, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_9},
    {16, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_5},
    {17, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_6},
    {18, RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_6},
    {19, RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_7},
    {20, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_9},
    {21, RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_8},

    {22, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_12},
    {23, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_2},
    {24, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_1},
    {25, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_0},
    {26, RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_9},
    {27, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_13},
    {28, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_15},
    {29, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_12},
    {30, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_10},
    {31, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_8},
    {32, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_7},
    {33, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_4},
    {34, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_3},
    {35, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_2},
    {36, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_1},
    {37, RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_0},
    {38, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_11},
    {39, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_10},
    {40, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_7},
    {41, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_3},
    {42, RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_4},
    {43, RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_8},
    {44, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_15},
    {45, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_14},
    {46, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_11},
    {47, RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_5},
    {48, RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_10},
    {49, RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_15},
    {50, RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_4},
    {51, RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_7},
    {52, RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_3},
    {53, RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_4},
};

91 92
#define ITEM_NUM(items) sizeof(items)/sizeof(items[0])
const struct pin_index *get_pin(uint8_t pin)
93
{
94
    const struct pin_index *index;
95

96
    if (pin < ITEM_NUM(pins))
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
    {
        index = &pins[pin];
    }
    else
    {
        index = RT_NULL;
    }

    return index;
};

void stm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
    const struct pin_index *index;

    index = get_pin(pin);
113
    if (index == RT_NULL)
114 115 116 117
    {
        return;
    }

118
    if (value == PIN_LOW)
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
    {
        GPIO_ResetBits(index->gpio, index->pin);
    }
    else
    {
        GPIO_SetBits(index->gpio, index->pin);
    }
}

int stm32_pin_read(rt_device_t dev, rt_base_t pin)
{
    int value;
    const struct pin_index *index;

    value = PIN_LOW;

    index = get_pin(pin);
136
    if (index == RT_NULL)
137 138 139 140
    {
        return value;
    }

141
    if (GPIO_ReadInputDataBit(index->gpio, index->pin) == Bit_RESET)
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
    {
        value = PIN_LOW;
    }
    else
    {
        value = PIN_HIGH;
    }

    return value;
}

void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
    const struct pin_index *index;
    GPIO_InitTypeDef  GPIO_InitStructure;

    index = get_pin(pin);
159
    if (index == RT_NULL)
160 161 162 163 164 165 166 167 168 169 170 171
    {
        return;
    }

    /* GPIO Periph clock enable */
    RCC_AHB1PeriphClockCmd(index->rcc, ENABLE);

    /* Configure GPIO_InitStructure */
    GPIO_InitStructure.GPIO_Pin     = index->pin;
    GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;

172
    if (mode == PIN_MODE_OUTPUT)
173 174 175 176 177
    {
        /* output setting */
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    }
178
    else if (mode == PIN_MODE_INPUT)
179 180 181 182 183
    {
        /* input setting: not pull. */
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    }
184
    else if (mode == PIN_MODE_INPUT_PULLUP)
185 186 187 188 189 190 191 192 193 194 195 196 197 198
    {
        /* input setting: pull up. */
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    }
    else
    {
        /* input setting:default. */
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
    }
    GPIO_Init(index->gpio, &GPIO_InitStructure);
}

199
const static struct rt_pin_ops _stm32_pin_ops =
200 201 202 203 204 205 206 207 208 209 210 211 212 213
{
    stm32_pin_mode,
    stm32_pin_write,
    stm32_pin_read,
};

int stm32_hw_pin_init(void)
{
    rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);
    return 0;
}
INIT_BOARD_EXPORT(stm32_hw_pin_init);

#endif