Skip to content

Latest commit

 

History

History
329 lines (236 loc) · 7.89 KB

README.md

File metadata and controls

329 lines (236 loc) · 7.89 KB

VT1211 GPIO Library

Userspace библиотека для работы с портами GPIO Super I/O контроллера VIA VT1211. Была написана в процессе раскуривания работы контроллера. Выложена в академических целях, позволяет разобраться в работе с контроллером, не отвлекаясь на API ядра Linux. Использовать её для решения реальных задач не рекомендую, ибо это не Ъ-way.

git репозиторий с модулем ядра

По ссылке вы найдёте готовый модуль ядра, а также описание работы с контроллером.

Сборка и установка

Все действия выполняются под Debian GNU/Linux (Stretch)

Установим необходимые пакеты

# apt install git automake autoconf build-essential

Получим, соберём, и установим библиотеку

# cd /usr/local/src
# git clone https://github.com/manfredmann/vt1211_gpio
# cd vt1211_gpio
# autoreconf -vi
# ./configure --prefix=/usr/local
# make
# make install
# ls -la /usr/local/lib | grep gpio
-rw-r--r-- 1 root staff 36718 Feb 25 16:21 libvt1211_gpio.a
# 
# ls -la /usr/local/include | grep gpio
-rw-r--r-- 1 root staff 3067 Feb 25 16:21 vt1211_gpio.h

Пример простой программы

Сгенерируем прямоугольник на 1 ноге порта 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <vt1211_gpio.h>

int main(int argc, char *argv[]) {
  printf("==============================================\n");
  printf("Request I/O privileges:\t");

  if (!io_request()) {
    printf("ERROR\n");
    return EXIT_FAILURE;
  } else {
    printf("OK\n");
  }

  printf("VT1211 Init:\t\t");

  int r = vt_init(VT_CONFIG_PORT_1 | VT_CONFIG_PORT_3_6, 0x2E, 0x2F);

  switch (r) {
    case VT_INIT_NOT_FOUND: {
      printf("ERROR VT1211 Not found\n");
      printf("==============================================\n");
      return EXIT_FAILURE;
    }
    case VT_INIT_NO_PORT: {
      printf("ERROR No port selected\n");
      printf("==============================================\n");
      return EXIT_FAILURE;
    }
    case VT_INIT_OK:
    default: {
      printf("OK\n");
    }
  }

  uint8_t vt_id     = vt_get_dev_id();
  uint8_t vt_rev    = vt_get_dev_rev();
  uint16_t vt_base  = vt_get_baddr();

  printf("VT1211 ID: %02X, Revision: %02X, Base addr.: %04x\n", vt_id, vt_rev, vt_base);
  printf("==============================================\n");

  vt_port_mode(VT_PORT_1, VT_PORT_OUTPUT);
  vt_port_polarity(VT_PORT_1, VT_PORT_PL_DIRECT);
  vt_port_write(VT_PORT_1, 0x00);

  while(1) {
    vt_pin_hi(VT_PORT_1, VT_PIN_0);
    usleep(1000);
    vt_pin_low(VT_PORT_1, VT_PIN_0);
    usleep(1000);
  }

  return EXIT_SUCCESS;
}

Соберём и запустим. ВНИМАНИЕ! Запускать от имени root, иначе не удастся получить доступ к пространству I/O

# gcc main.c -lvt1211_gpio -o vt1211_test
# ./vt1211_test
==============================================
Request I/O privileges: OK
VT1211 Init:            OK
VT1211 ID: 3C, Revision: 02, Base addr.: 0800
==============================================

Подключим осциллограф к 1 ноге порта 1, и увидим:

Scheme

API

int       vt_init(uint8_t ports);

Инициализация контроллера.

Параметры

  • uint8_t ports - Какие порты использовать

Возвращаемое значение

Смотри defines


uint8_t   vt_get_dev_id();

Возвращает идентификатор Super I/O контроллера


uint8_t   vt_get_dev_rev();

Возвращает ревизию Super I/O контроллера


uint16_t  vt_get_baddr();

Возвращает базовый адрес в пространстве I/O для работы с портами.


void      vt_port_mode(uint8_t port, uint8_t mode);

Установка режима работы порта. На ввод или вывод

Параметры

  • uint8_t port - Номер порта
  • uint8_t mode - Режим работы порта

void      vt_port_polarity(uint8_t port, uint8_t polarity);

Инверсия разрядов порта

Параметры

  • uint8_t port - Номер порта
  • uint8_t polarity - Прямой/инверсный

void      vt_port_write(uint8_t port, uint8_t data);

Запись в порт

Параметры

  • uint8_t port - Номер порта
  • uint8_t data - Данные

uint8_t   vt_port_read(uint8_t port);

Чтение порта

Возвращаемое значение

Прочитанные данные


void      vt_pin_mode(uint8_t port, uint8_t pin, uint8_t mode);

Режим работы пина. Ввод или вывод

Параметры

  • uint8_t port - Номер порта
  • uint8_t pin - Номер пина
  • uint8_t mode - Режим работы пина

void      vt_pin_polarity(uint8_t port, uint8_t pin, uint8_t polarity);

Инверсия пина

Параметры

  • uint8_t port - Номер порта
  • uint8_t pin - Номер пина
  • uint8_t polarity - Прямой/инверсный

void      vt_pin_set(uint8_t port, uint8_t pin, uint8_t value);

Установить пин в 0 или 1

Параметры

  • uint8_t port - Номер порта
  • uint8_t pin - Номер пина
  • uint8_t value - 0 или 1

uint8_t   vt_pin_get(uint8_t port, uint8_t pin);

Прочитать значение пина

Параметры

  • uint8_t port - Номер порта
  • uint8_t pin - Номер пина

Возвращаемое значение

Значение пина


DEFINES

Порты для инициализации

#define VT_CONFIG_PORT_1              0x01
#define VT_CONFIG_PORT_3_6            0x04

Возвращаемые значения функции инициализации

#define VT_INIT_OK                    0x00
#define VT_INIT_NOT_FOUND             0x01
#define VT_INIT_NO_PORT               0x02

Номера портов

#define VT_PORT_1                     0x00 //GP10...GP17
#define VT_PORT_3                     0x01 //GP30...GP37
#define VT_PORT_4                     0x02 //GP40...GP47
#define VT_PORT_5                     0x03 //GP50...GP57
#define VT_PORT_6                     0x04 //GP60...GP62

Режим работы порта. Ввод или вывод

#define VT_PORT_INPUT                 0x00
#define VT_PORT_OUTPUT                0xFF

Инверсия разрядов порта

#define VT_PORT_PL_DIRECT             0x00
#define VT_PORT_PL_INVERSE            0xFF

Режим работы отдельного пина. Ввод или вывод.

#define VT_PIN_INPUT                  0x1
#define VT_PIN_OUTPUT                 0x0

Инверсия одного пина

#define VT_PIN_PL_DIRECT              0x0
#define VT_PIN_PL_INVERSE             0x1

Номера пинов

#define VT_PIN_0                     (0x1)
#define VT_PIN_1                     (0x1 << 1)
#define VT_PIN_2                     (0x1 << 2)
#define VT_PIN_3                     (0x1 << 3)
#define VT_PIN_4                     (0x1 << 4)
#define VT_PIN_5                     (0x1 << 5)
#define VT_PIN_6                     (0x1 << 6)
#define VT_PIN_7                     (0x1 << 7)