#include #include #include #include #include #include #include #include "gpio.h" using namespace std; // The number is indicating which GPIO Module(0-3) of // each pin belongs to. // const int BeagleGPIO::pinBank[] = { -1, -1, 1, 1, 1, // P8_1 -> P8_5 1, 2, 2, 2, 2, // P8_6 -> P8_10 1, 1, 0, 0, 1, // P8_11 -> P8_15 1, 0, 2, 0, 1, // P8_16 -> P8_20 1, 1, 1, 1, 1, // P8_21 -> P8_25 1, 2, 2, 2, 2, // P8_26 -> P8_30 0, 0, 0, 2, 0, // P8_31 -> P9_35 2, 2, 2, 2, 2, // P8_36 -> P8_40 2, 2, 2, 2, 2, // P8_41 -> P8_45 2, // P8_46 -1, -1, -1, -1, -1, // P9_1 -> P9_5 -1, -1, -1, -1, -1, // P9_6 -> P9_10 0, 1, 0, 1, 1, // P9_11 -> P9_15 1, 0, 0, 0, 0, // P9_16 -> P9_20 0, 0, 1, 0, 3, // P9_21 -> P9_25 0, 3, 3, 3, 3, // P9_26 -> P9_30 3, -1, -1, -1, -1, // P9_31 -> P9_35 -1, -1, -1, -1, -1, // P9_36 -> P9_40 0, 0, -1, -1, -1, // P9_41 -> P9_45 -1 // P9_46 }; // Pin ID: if it is -1, it means that it is not a GPIO pin // If it is a GPIO Pin, the number is indicating the position // of GPIO_DATAIN and GPIO_DATAOUT registers. const int BeagleGPIO::pinId[] = { -1, -1, 6, 7, 2, // P8_1 -> P8_5 3, 2, 3, 5, 4, // P8_6 -> P8_10 13, 12, 23, 26, 15, // P8_11 -> P8_15 14, 27, 1, 22, 31, // P8_16 -> P8_20 30, 5, 4, 1, 0, // P8_21 -> P8_25 29, 22, 24, 23, 25, // P8_26 -> P8_30 10, 11, 9, 17, 8, // P8_31 -> P9_35 16, 14, 15, 12, 13, // P8_36 -> P8_40 10, 11, 8, 9, 6, // P8_41 -> P8_45 7, // P8_46 -1, -1, -1, -1, -1, // P9_1 -> P9_5 -1, -1, -1, -1, -1, // P9_6 -> P9_10 30, 28, 31, 18, 16, // P9_11 -> P9_15 19, 5, 4, 13, 12, // P9_16 -> P9_20 3, 2, 17, 15, 21, // P9_21 -> P9_25 14, 19, 17, 15, 16, // P9_26 -> P9_30 14, -1, -1, -1, -1, // P9_31 -> P9_35 -1, -1, -1, -1, -1, // P9_36 -> P9_40 20, 7, -1, -1, -1, // P9_41 -> P9_45 -1 // P9_46 }; // Pad Control Register // The addresses of registers, which control the Pin Mux of // each GPIO Pins const unsigned long BeagleGPIO::padControl[] = { 0x0000, 0x0000, 0x0818, 0x081C, 0x0808, // P8_1 -> P8_5 0x080C, 0x0890, 0x0894, 0x089C, 0x0898, // P8_6 -> P8_10 0x0834, 0x0830, 0x0824, 0x0828, 0x083C, // P8_11 -> P8_15 0x0838, 0x082C, 0x088C, 0x0820, 0x0884, // P8_16 -> P8_20 0x0880, 0x0814, 0x0810, 0x0804, 0x0800, // P8_21 -> P8_25 0x087C, 0x08E0, 0x08E8, 0x08E4, 0x08EC, // P8_26 -> P8_30 0x08D8, 0x08DC, 0x08D4, 0x08CC, 0x08D0, // P8_31 -> P8_35 0x08C8, 0x08C0, 0x08C4, 0x08B8, 0x08BC, // P8_36 -> P8_40 0x08B0, 0x08B4, 0x08A8, 0x08AC, 0x08A0, // P8_41 -> P8_45 0x08A4, // P8_46 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // P9_1 -> P9_5 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // P9_6 -> P9_10 0x0870, 0x0878, 0x0874, 0x0848, 0x0840, // P9_11 -> P9_15 0x084C, 0x095C, 0x0958, 0x097C, 0x0978, // P9_16 -> P9_20 0x0954, 0x0950, 0x0844, 0x0984, 0x09AC, // P9_21 -> P9_25 0x0980, 0x09A4, 0x099C, 0x0994, 0x0998, // P9_26 -> P9_30 0x0990, 0x0000, 0x0000, 0x0000, 0x0000, // P9_31 -> P9_35 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // P9_36 -> P9_40 0x09B4, 0x0964, 0x0000, 0x0000, 0x0000, // P9_41 -> P9_45 0x0000 // P9_46 }; // Control Module Registers: Please refer to Memory Map of // AM335x MCU const unsigned long BeagleGPIO::ctrlModuleReg = 0x44E10000; // GPIO Module registers const unsigned long BeagleGPIO::GpioBaseReg[] = { 0x44E07000, // GPIO0 0x4804C000, // GPIO1 0x481AC000, // GPIO2 0x481AE000 // GPIO3 }; //======================================================= //======================================================= BeagleGPIO::BeagleGPIO() { // Not initialized by default mActive = false; system("echo 5 > /sys/class/gpio/export > /dev/null"); system("echo 65 > /sys/class/gpio/export > /dev/null"); system("echo 105 > /sys/class/gpio/export > /dev/null"); // Opening /dev/mem first m_gpio_fd = open( "/dev/mem", O_RDWR | O_SYNC ); if ( m_gpio_fd < 0 ) { GPIO_ERROR( "Cannot open /dev/mem" ); return; } // Map Control Module mControlModule = (unsigned long *)mmap( NULL, 0x1FFF, PROT_READ | PROT_WRITE, MAP_SHARED, m_gpio_fd, ctrlModuleReg ); if ( mControlModule == MAP_FAILED ) { GPIO_ERROR( "Control Module Mapping failed" ); return; } // Now mapping the GPIO registers for ( int i=0; i<4; ++i) { // Map a GPIO bank m_gpio[i] = (unsigned long *)mmap( NULL, 0xFFF, PROT_READ | PROT_WRITE, MAP_SHARED, m_gpio_fd, GpioBaseReg[i] ); if ( m_gpio[i] == MAP_FAILED ) { GPIO_ERROR( "GPIO Mapping failed for GPIO Module " << i ); return; } } // Init complete and successfull mActive = true; } //------------------------------------------------------- // //Disstructor // //------------------------------------------------------- BeagleGPIO::~BeagleGPIO() { if ( mActive && m_gpio_fd) close( m_gpio_fd ); } //------------------------------------------------------- // // Configure pin as input/output // //------------------------------------------------------- BeagleGPIO::Status BeagleGPIO::configPin( unsigned short _pin, Direction _direction ) { if ( !mActive ) return kFail; //assert(pinBank[_pin]>=0); //assert(pinId[_pin]>=0); // Set Pin as GPIO on the pad control mControlModule[padControl[_pin]/4] |= 0x07; unsigned long v = 0x1 << pinId[_pin]; if ( _direction == kINPUT) { m_gpio[pinBank[_pin]][kOE/4] |= v; } else { m_gpio[pinBank[_pin]][kOE/4] &= ~v; } // Disable Interrupts by default m_gpio[pinBank[_pin]][kIRQSTATUS_CLR_0/4] |= v; m_gpio[pinBank[_pin]][kIRQSTATUS_CLR_1/4] |= v; return kSuccess; } //------------------------------------------------------- // //! Write a value to a Pin // //! return status // //------------------------------------------------------- BeagleGPIO::Status BeagleGPIO::writePin( unsigned short _pin, unsigned char _value ) { //assert(pinBank[_pin]>=0); //assert(pinId[_pin]>=0); unsigned long v = (_value & 0x01) << pinId[_pin]; unsigned long mask = 0x1 << pinId[_pin]; // Remove bit m_gpio[pinBank[_pin]][kDATAOUT/4] &= ~mask; // Assign new bit value m_gpio[pinBank[_pin]][kDATAOUT/4] |= v; return kSuccess; } //------------------------------------------------------- // // Read a value from a pin // //------------------------------------------------------- unsigned char BeagleGPIO::readPin( unsigned short _pin ) { //assert(pinBank[_pin]>=0); //assert(pinId[_pin]>=0); unsigned long bit = pinId[_pin]; return (m_gpio[pinBank[_pin]][kDATAIN/4] & (0x1 << bit)) >> bit; }