Statistics
| Branch: | Tag: | Revision:

root / host / lib / usrp / cores / gpio_core_200.cpp @ 7c8fef85

History | View | Annotate | Download (4.08 KB)

1
//
2
// Copyright 2011 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

    
18
#include "gpio_core_200.hpp"
19
#include <uhd/types/dict.hpp>
20

    
21
#define REG_GPIO_IDLE          _base + 0
22
#define REG_GPIO_RX_ONLY       _base + 4
23
#define REG_GPIO_TX_ONLY       _base + 8
24
#define REG_GPIO_BOTH          _base + 12
25
#define REG_GPIO_DDR           _base + 16
26

    
27
using namespace uhd;
28
using namespace usrp;
29

    
30
class gpio_core_200_impl : public gpio_core_200{
31
public:
32
    gpio_core_200_impl(wb_iface::sptr iface, const size_t base, const size_t rb_addr):
33
        _iface(iface), _base(base), _rb_addr(rb_addr) { /* NOP */ }
34

    
35
    void set_pin_ctrl(const unit_t unit, const boost::uint16_t value){
36
        _pin_ctrl[unit] = value; //shadow
37
        this->update(); //full update
38
    }
39

    
40
    void set_atr_reg(const unit_t unit, const atr_reg_t atr, const boost::uint16_t value){
41
        _atr_regs[unit][atr] = value;  //shadow
42
        this->update(); //full update
43
    }
44

    
45
    void set_gpio_ddr(const unit_t unit, const boost::uint16_t value){
46
        _gpio_ddr[unit] = value; //shadow
47
        _iface->poke32(REG_GPIO_DDR, //update the 32 bit register
48
            (boost::uint32_t(_gpio_ddr[dboard_iface::UNIT_RX]) << unit2shit(dboard_iface::UNIT_RX)) |
49
            (boost::uint32_t(_gpio_ddr[dboard_iface::UNIT_TX]) << unit2shit(dboard_iface::UNIT_TX))
50
        );
51
    }
52

    
53
    void set_gpio_out(const unit_t unit, const boost::uint16_t value){
54
        _gpio_out[unit] = value; //shadow
55
        this->update(); //full update
56
    }
57

    
58
    boost::uint16_t read_gpio(const unit_t unit){
59
        return boost::uint16_t(_iface->peek32(_rb_addr) >> unit2shit(unit));
60
    }
61

    
62
private:
63
    wb_iface::sptr _iface;
64
    const size_t _base;
65
    const size_t _rb_addr;
66
    uhd::dict<size_t, boost::uint32_t> _update_cache;
67

    
68
    uhd::dict<unit_t, boost::uint16_t> _pin_ctrl, _gpio_out, _gpio_ddr;
69
    uhd::dict<unit_t, uhd::dict<atr_reg_t, boost::uint16_t> > _atr_regs;
70

    
71
    unsigned unit2shit(const unit_t unit){
72
        return (unit == dboard_iface::UNIT_RX)? 0 : 16;
73
    }
74

    
75
    void update(void){
76
        this->update(dboard_iface::ATR_REG_IDLE, REG_GPIO_IDLE);
77
        this->update(dboard_iface::ATR_REG_TX_ONLY, REG_GPIO_TX_ONLY);
78
        this->update(dboard_iface::ATR_REG_RX_ONLY, REG_GPIO_RX_ONLY);
79
        this->update(dboard_iface::ATR_REG_FULL_DUPLEX, REG_GPIO_BOTH);
80
    }
81

    
82
    void update(const atr_reg_t atr, const size_t addr){
83
        const boost::uint32_t atr_val =
84
            (boost::uint32_t(_atr_regs[dboard_iface::UNIT_RX][atr]) << unit2shit(dboard_iface::UNIT_RX)) |
85
            (boost::uint32_t(_atr_regs[dboard_iface::UNIT_TX][atr]) << unit2shit(dboard_iface::UNIT_TX));
86

    
87
        const boost::uint32_t gpio_val =
88
            (boost::uint32_t(_gpio_out[dboard_iface::UNIT_RX]) << unit2shit(dboard_iface::UNIT_RX)) |
89
            (boost::uint32_t(_gpio_out[dboard_iface::UNIT_TX]) << unit2shit(dboard_iface::UNIT_TX));
90

    
91
        const boost::uint32_t ctrl =
92
            (boost::uint32_t(_pin_ctrl[dboard_iface::UNIT_RX]) << unit2shit(dboard_iface::UNIT_RX)) |
93
            (boost::uint32_t(_pin_ctrl[dboard_iface::UNIT_TX]) << unit2shit(dboard_iface::UNIT_TX));
94
        const boost::uint32_t val = (ctrl & atr_val) | ((~ctrl) & gpio_val);
95
        if (not _update_cache.has_key(addr) or _update_cache[addr] != val)
96
        {
97
            _iface->poke32(addr, val);
98
        }
99
        _update_cache[addr] = val;
100
    }
101

    
102
};
103

    
104
gpio_core_200::sptr gpio_core_200::make(wb_iface::sptr iface, const size_t base, const size_t rb_addr){
105
    return sptr(new gpio_core_200_impl(iface, base, rb_addr));
106
}