source: EP9302-digital/digital.c

Last change on this file was 1, checked in by mancausoft, 13 years ago

Added Library to read and write digital for arm9 EP9302

File size: 6.0 KB
Line 
1/*
2 *  EP9302 Digital library
3 *  Copyright (C) 2010  Andrea Milazzo aka Mancausoft
4 *
5 *  This program is free software: you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation, either version 3 of the License, or
8 *  (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <unistd.h>
20#include <sys/types.h>
21#include <sys/mman.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <fcntl.h>
25#include <assert.h>
26#include <stdint.h>
27#include <stdbool.h>
28#include "digital.h"
29
30
31
32/* globals */
33static unsigned long data_page, syscon_page;
34
35static volatile uint8_t* port[8], *portd[8];
36
37
38/**
39 * Set a bit of HW Port.
40 * \param nport The HW port to set. The value must be betwen 0 and 7.
41 * \param value The value of bit to set.
42 * \param pos The position of bit to set.
43 * \return The value returned is -1 if the param nport is incorrect.
44 *  Otherwise return 0.
45 */
46int set_port_bit (uint8_t nport, bool value, uint8_t pos)
47{
48        if(nport < 8 && pos < 8)
49        {
50                set_bit(value, port[nport], pos);
51                return 0;
52        }
53        return -1;
54}
55
56/**
57 * Get a bit of HW Port.
58 * \param nport The HW port to get. The value must be betwen 0 and 7.
59 * \param value The pointer to the return value.
60 * \param pos The position of bit to get.
61 * \return The value returned is -1 if the param nport is incorrect.
62 *  Otherwise return 0.
63 */
64int get_port_bit (uint8_t nport, bool* value, uint8_t pos)
65{
66        if(nport < 8 && pos < 8)
67        {
68                get_bit(*port[nport], value, pos);
69                return 0;
70        }
71        return -1;
72}
73
74/**
75 * Set direction bit of HW Port.
76 * \param nport The HW port to set. The value must be betwen 0 and 7.
77 * \param value The value of direction bit to set.
78 * \param pos The position of direction bit to set.
79 * \return The value returned is -1 if the param nport is incorrect.
80 *  Otherwise return 0.
81 */
82int set_port_dir_bit (uint8_t nport, bool value, uint8_t pos)
83{
84        if(nport < 8 && pos < 8)
85        {
86                set_bit(value, portd[nport], pos);
87                return 0;
88        }
89        return -1;
90}
91
92/**
93 * Get direction bit of HW Port.
94 * \param nport The HW port to get. The value must be betwen 0 and 7.
95 * \param value The pointer to the return value.
96 * \param pos The position of direction bit to get.
97 * \return The value returned is -1 if the param nport is incorrect.
98 *  Otherwise return 0.
99 */
100int get_port_dir_bit (uint8_t nport, bool* value, uint8_t pos)
101{
102        if(nport < 8 && pos < 8)
103        {
104                get_bit(*portd[nport], value, pos);
105                return 0;
106        }
107        return -1;
108}
109
110/**
111 * Set direction of HW Port.
112 * \param nport The HW port to set. The value must be betwen 0 and 7.
113 * \param value The value of direction to set.
114 * \return The value returned is -1 if the param nport is incorrect.
115 *  Otherwise return 0.
116 */
117int set_port_dir(uint8_t nport, uint8_t value)
118{
119        if(nport < 8)
120        {
121                *portd[nport] = value;
122                return 0;
123        }
124        return -1;
125}
126
127/**
128 * Get direction of HW Port.
129 * \param nport The HW port to get. The value must be betwen 0 and 7.
130 * \param value The pointer to the return value.
131 * \return The value returned is -1 if the param nport is incorrect.
132 *  Otherwise return 0.
133 */
134int get_port_dir(uint8_t nport, uint8_t* value)
135{
136        if(nport < 8)
137        {
138                *value = *portd[nport];
139                return 0;
140        }
141        return -1;
142}
143
144/**
145 * Set value of HW Port.
146 * \param nport The HW port to set. The value must be betwen 0 and 7.
147 * \param value The value to set.
148 * \return The value returned is -1 if the param nport is incorrect.
149 *  Otherwise return 0.
150 */
151int set_port (uint8_t nport, uint8_t value)
152{
153        if(nport < 8)
154        {
155                *port[nport] = value;
156                return 0;
157        }
158        return -1;
159}
160
161/**
162 * Get value of HW Port.
163 * \param nport The HW port to get. The value must be betwen 0 and 7.
164 * \param value The pointer to the return value.
165 * \return The value returned is -1 if the param nport is incorrect.
166 *  Otherwise return 0.
167 */
168int get_port (uint8_t nport, uint8_t* value)
169{
170        if(nport < 8)
171        {
172                *value = *port[nport];
173                return 0;
174        }
175        return -1;
176}
177
178/**
179 * Do intial setting to use HW port.
180 * \return The /dev/mem file descriptor.
181 */
182int init_ports()
183{
184        int devmem = open("/dev/mem", O_RDWR|O_SYNC);
185        assert(devmem != -1);
186
187        data_page = (unsigned long)mmap(0, getpagesize(), PROT_READ|PROT_WRITE,
188                MAP_SHARED, devmem, DATA_PAGE);
189        assert (&data_page != MAP_FAILED);
190
191        syscon_page = (unsigned long)mmap(0, getpagesize(), PROT_READ|PROT_WRITE
192                , MAP_SHARED, devmem, SYSCON_PAGE);
193        assert(&syscon_page != MAP_FAILED);
194
195        uint32_t* deviceCfg = (uint32_t*) (syscon_page + DEVICECFG);
196        uint32_t* syscon_unlock = (uint32_t*) (syscon_page + SYSCON_UNLOCK);
197
198        *syscon_unlock = UNLOCK_VAL;
199        // TonG = 1  HonIDE = 1 GonIDE = 1 EonIDE = 1
200        *deviceCfg |= 0x08000D00;
201
202        port[0] = (uint8_t*) (data_page + PADR);
203        port[1] = (uint8_t*) (data_page + PBDR);
204        port[2] = (uint8_t*) (data_page + PCDR);
205        port[3] = (uint8_t*) (data_page + PDDR);
206        port[4] = (uint8_t*) (data_page + PEDR);
207        port[5] = (uint8_t*) (data_page + PFDR);
208        port[6] = (uint8_t*) (data_page + PGDR);
209        port[7] = (uint8_t*) (data_page + PHDR);
210
211        portd[0] = (uint8_t*) (data_page + PADDR);
212        portd[1] = (uint8_t*) (data_page + PBDDR);
213        portd[2] = (uint8_t*) (data_page + PCDDR);
214        portd[3] = (uint8_t*) (data_page + PDDDR);
215        portd[4] = (uint8_t*) (data_page + PEDDR);
216        portd[5] = (uint8_t*) (data_page + PFDDR);
217        portd[6] = (uint8_t*) (data_page + PGDDR);
218        portd[7] = (uint8_t*) (data_page + PHDDR);
219
220    return devmem;
221}
222
223/**
224 * Close /dev/mem.
225 * \param devmem The /dev/mem file descriptor.
226 */
227void close_ports(int devmem)
228{
229        close(devmem);
230}
231
232inline void set_bit(bool src, volatile uint8_t *dst, uint8_t bit)
233{
234        int value = 1 << bit;
235        if(src)
236                *dst |= value;
237        else
238                *dst &= ~value;
239}
240
241inline void get_bit(volatile uint8_t src, bool *dst, uint8_t bit)
242{
243        int value = 1 << bit;
244        *dst = (src & value) >> bit;
245}
246
Note: See TracBrowser for help on using the repository browser.