/* * EP9302 Digital library * Copyright (C) 2010 Andrea Milazzo aka Mancausoft * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include "digital.h" /* globals */ static unsigned long data_page, syscon_page; static volatile uint8_t* port[8], *portd[8]; /** * Set a bit of HW Port. * \param nport The HW port to set. The value must be betwen 0 and 7. * \param value The value of bit to set. * \param pos The position of bit to set. * \return The value returned is -1 if the param nport is incorrect. * Otherwise return 0. */ int set_port_bit (uint8_t nport, bool value, uint8_t pos) { if(nport < 8 && pos < 8) { set_bit(value, port[nport], pos); return 0; } return -1; } /** * Get a bit of HW Port. * \param nport The HW port to get. The value must be betwen 0 and 7. * \param value The pointer to the return value. * \param pos The position of bit to get. * \return The value returned is -1 if the param nport is incorrect. * Otherwise return 0. */ int get_port_bit (uint8_t nport, bool* value, uint8_t pos) { if(nport < 8 && pos < 8) { get_bit(*port[nport], value, pos); return 0; } return -1; } /** * Set direction bit of HW Port. * \param nport The HW port to set. The value must be betwen 0 and 7. * \param value The value of direction bit to set. * \param pos The position of direction bit to set. * \return The value returned is -1 if the param nport is incorrect. * Otherwise return 0. */ int set_port_dir_bit (uint8_t nport, bool value, uint8_t pos) { if(nport < 8 && pos < 8) { set_bit(value, portd[nport], pos); return 0; } return -1; } /** * Get direction bit of HW Port. * \param nport The HW port to get. The value must be betwen 0 and 7. * \param value The pointer to the return value. * \param pos The position of direction bit to get. * \return The value returned is -1 if the param nport is incorrect. * Otherwise return 0. */ int get_port_dir_bit (uint8_t nport, bool* value, uint8_t pos) { if(nport < 8 && pos < 8) { get_bit(*portd[nport], value, pos); return 0; } return -1; } /** * Set direction of HW Port. * \param nport The HW port to set. The value must be betwen 0 and 7. * \param value The value of direction to set. * \return The value returned is -1 if the param nport is incorrect. * Otherwise return 0. */ int set_port_dir(uint8_t nport, uint8_t value) { if(nport < 8) { *portd[nport] = value; return 0; } return -1; } /** * Get direction of HW Port. * \param nport The HW port to get. The value must be betwen 0 and 7. * \param value The pointer to the return value. * \return The value returned is -1 if the param nport is incorrect. * Otherwise return 0. */ int get_port_dir(uint8_t nport, uint8_t* value) { if(nport < 8) { *value = *portd[nport]; return 0; } return -1; } /** * Set value of HW Port. * \param nport The HW port to set. The value must be betwen 0 and 7. * \param value The value to set. * \return The value returned is -1 if the param nport is incorrect. * Otherwise return 0. */ int set_port (uint8_t nport, uint8_t value) { if(nport < 8) { *port[nport] = value; return 0; } return -1; } /** * Get value of HW Port. * \param nport The HW port to get. The value must be betwen 0 and 7. * \param value The pointer to the return value. * \return The value returned is -1 if the param nport is incorrect. * Otherwise return 0. */ int get_port (uint8_t nport, uint8_t* value) { if(nport < 8) { *value = *port[nport]; return 0; } return -1; } /** * Do intial setting to use HW port. * \return The /dev/mem file descriptor. */ int init_ports() { int devmem = open("/dev/mem", O_RDWR|O_SYNC); assert(devmem != -1); data_page = (unsigned long)mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, devmem, DATA_PAGE); assert (&data_page != MAP_FAILED); syscon_page = (unsigned long)mmap(0, getpagesize(), PROT_READ|PROT_WRITE , MAP_SHARED, devmem, SYSCON_PAGE); assert(&syscon_page != MAP_FAILED); uint32_t* deviceCfg = (uint32_t*) (syscon_page + DEVICECFG); uint32_t* syscon_unlock = (uint32_t*) (syscon_page + SYSCON_UNLOCK); *syscon_unlock = UNLOCK_VAL; // TonG = 1 HonIDE = 1 GonIDE = 1 EonIDE = 1 *deviceCfg |= 0x08000D00; port[0] = (uint8_t*) (data_page + PADR); port[1] = (uint8_t*) (data_page + PBDR); port[2] = (uint8_t*) (data_page + PCDR); port[3] = (uint8_t*) (data_page + PDDR); port[4] = (uint8_t*) (data_page + PEDR); port[5] = (uint8_t*) (data_page + PFDR); port[6] = (uint8_t*) (data_page + PGDR); port[7] = (uint8_t*) (data_page + PHDR); portd[0] = (uint8_t*) (data_page + PADDR); portd[1] = (uint8_t*) (data_page + PBDDR); portd[2] = (uint8_t*) (data_page + PCDDR); portd[3] = (uint8_t*) (data_page + PDDDR); portd[4] = (uint8_t*) (data_page + PEDDR); portd[5] = (uint8_t*) (data_page + PFDDR); portd[6] = (uint8_t*) (data_page + PGDDR); portd[7] = (uint8_t*) (data_page + PHDDR); return devmem; } /** * Close /dev/mem. * \param devmem The /dev/mem file descriptor. */ void close_ports(int devmem) { close(devmem); } inline void set_bit(bool src, volatile uint8_t *dst, uint8_t bit) { int value = 1 << bit; if(src) *dst |= value; else *dst &= ~value; } inline void get_bit(volatile uint8_t src, bool *dst, uint8_t bit) { int value = 1 << bit; *dst = (src & value) >> bit; }