2017-01-06 2 views
1

Я пытаюсь установить Pin G11 на NanoPi Neo, ранее настроенный как вход, для вывода на C++ путем сопоставления регистра функции PIO в виртуальной памяти с mmap и установки одного бита.Как установить GPIO NanoPi как выход на аппаратном уровне?

Per Allwinner H3 Datasheet указаны следующие аппаратные адреса:

PIO Base Адрес: 0x01C20800 (стр. 316)

PG Настройка Регистрация 1 смещение: 0xDC (стр. 338)

PG11 бит: 14:12

Как и в регистре функций малины Pi, Pin знает как минимум два состояния:

000: input 
001: output 

В моем сценарии, я поэтому пытается установить 12-й бит PG Настройка регистра 1. Вот мой C++ код:

struct peripheral { 
    unsigned long addr_hardware; 
    int map_size; 
    int mem_fd; 
    void *mem_map; 
    volatile unsigned long *addr_virtual; 

    int map() { 
     if ((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) return -1; 
     // map addr_hardware=0x01C20000 into /dev/mem 
     if ((mem_map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, addr_hardware)) == MAP_FAILED) return -1; 
     // store virtual address with offset of 0x800, which was rounded down before 
     addr_virtual = (volatile unsigned long *) mem_map + 0x800; 
     return 0; 
    }; 
    void unmap() { 
     munmap(mem_map, map_size); 
     close(mem_fd); 
    }; 
}; 

int main() { 
    // initialize peripheral at rounded down PIO base address 
    peripheral gpio {0x01C20000, 4096 * 10}; 
    // map PIOs into virtual memory 
    if (gpio.map() == -1) return -1; 

    // output current value of PG Configure Register 1 
    cout << bitset<32>(*(gpio.addr_virtual + 0xDC)) << endl; 
    // set 12th bit 
    *(gpio.addr_virtual + 0xDC) |= (1 << 12); 
    // output value of register after setting the 12th bit 
    cout << bitset<32>(*(gpio.addr_virtual + 0xDC)) << endl; 

    gpio.unmap(); 
    return 0; 
} 

К сожалению, мой код не работает. Когда я снова запускаю сценарий, содержимое регистра конфигурации PIO изменилось на прежнее состояние. Когда я настраиваю Pin G11 как Output (через WiringNP), отображаемое значение не изменяется. Я проверяю правильную функциональность своего кода со светодиодом (он должен включаться, когда состояние изменяется с IN на OUT, потому что оно установлено на HIGH).

Когда я изменить map_size, я получаю следующие результаты (пробелы добавлены для лучшей читаемости):

> gpio {0x01C20000, 4096 * 2} 
< 00000000 00000000 00000000 00000000 
< 00000000 00000000 00010000 00000000 

> gpio {0x01C20000, 4096 * 10} 
< 00000000 00000000 00000000 00110011 
< 00000000 00000000 00000000 00110011 

Я ожидаю следующий результат:

> gpio {0x01C20000, 4096 * 10} 
< 00000000 00000000 00000000 00110011 
< 00000000 00000000 00010000 00110011 

ответ

0

если Pio определяется в устройстве дерево, ядро ​​будет контролировать и перезаписывать связанные регистры. например, если он хочет управлять мигающим светодиодом или другим io через эти регистры.

Смежные вопросы