Check in
[owTools.git] / src / owPiGPioInterface.cpp
1 // Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //  * Redistributions of source code must retain the above copyright
9 //    notice, this list of conditions and the following disclaimer.
10 //  * Redistributions in binary form must reproduce the above copyright
11 //    notice, this list of conditions and the following disclaimer in the
12 //    documentation and/or other materials provided with the
13 //    distribution.
14 //  * All advertising materials mentioning features or use of this
15 //    software must display the following acknowledgement: This product
16 //    includes software developed by tm3d.de and its contributors.
17 //  * Neither the name of tm3d.de nor the names of its contributors may
18 //    be used to endorse or promote products derived from this software
19 //    without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33
34 #include "owPiGPioInterface.h"
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <sys/mman.h>
39 #include <fcntl.h>    /* For O_RDWR */
40 #include <unistd.h>
41 #include <pthread.h>
42 #include <sched.h>
43 #include <memory.h>
44 #include <strings.h>
45
46 namespace gpio_1w {
47
48
49 #ifndef MAP_LOCKED
50 #define MAP_LOCKED 0
51 #endif
52 static volatile uint32_t pi_peri_phys =0;
53
54
55 #define GPIO_BASE  (pi_peri_phys + 0x00200000)
56 #define SYST_BASE  (pi_peri_phys + 0x00003000)
57
58 #define GPIO_LEN  0xB4
59 #define SYST_LEN  0x1C
60
61 #define USD(ms) {unsigned int t=TICK+ms;while (TICK<t);}
62
63
64 static int fdMem        = -1;
65
66 static volatile uint32_t * gpioReg = 0;
67 static volatile uint32_t * systReg = 0;
68
69 static volatile uint32_t * gpioReg_read = 0;
70
71
72
73
74 int gpio_reg;
75 int gpio_shift;
76 int gpio_shift_;
77 int gpio_mode_shift;
78
79 #define OW_SET_LOW gpioReg[gpio_reg] = (gpioReg[gpio_reg] & gpio_shift_) | (gpio_mode_shift);
80 #define OW_RELEASE_LOW gpioReg[gpio_reg] = (gpioReg[gpio_reg] & gpio_shift_) ;
81
82 #define SYST_CLO     1
83 #define TICK systReg[SYST_CLO]
84  
85
86 #define GPLEV0    13
87 #define GPCLR0    10
88 #define GPSET0     7
89
90 int BANK=0;//=(owpin>>5);
91 int BIT=0;//=(1<<(owpin&0x1F));
92
93 #define OW_READ ((*(gpioReg_read) & BIT) != 0) 
94
95 int piCores;
96
97 unsigned PIHardwareRevision(void)
98 {
99    static unsigned rev = 0;
100
101    FILE * filp;
102    char buf[512];
103    char term;
104
105    if (rev) return rev;
106
107    piCores = 0;
108
109    filp = fopen ("/proc/cpuinfo", "r");
110
111    if (filp != NULL)
112    {
113       while (fgets(buf, sizeof(buf), filp) != NULL)
114       {
115          if (piCores == 0)
116          {
117             if (!strncasecmp("model name", buf, 10))
118             {
119                if (strstr (buf, "ARMv6") != NULL)
120                {
121                   piCores = 1;
122                   pi_peri_phys = 0x20000000;
123             //      pi_dram_bus  = 0x40000000;
124              //     pi_mem_flag  = 0x0C;
125                }
126                else if (strstr (buf, "ARMv7") != NULL)
127                {
128                   piCores = 4;
129                   pi_peri_phys = 0x3F000000;
130                   //pi_dram_bus  = 0xC0000000;
131                   //pi_mem_flag  = 0x04;
132                }
133                else if (strstr (buf, "ARMv8") != NULL)
134                {
135                   piCores = 4;
136                   pi_peri_phys = 0x3F000000;
137                //   pi_dram_bus  = 0xC0000000;
138                 //  pi_mem_flag  = 0x04;
139                }
140             }
141          }
142
143          if (!strncasecmp("revision\t:", buf, 10))
144          {
145             if (sscanf(buf+10, "%x%c", &rev, &term) == 2)
146             {
147                if (term != '\n') rev = 0;
148                else rev &= 0xFFFFFF; /* mask out warranty bit */
149             }
150          }
151       }
152
153       fclose(filp);
154    }
155    return rev;
156 }
157
158
159
160
161
162
163 }
164 using namespace gpio_1w;
165
166
167 int owPiGPioInterface::InitAdapter(uint8_t pin){
168     owpin=pin;
169     PIHardwareRevision();
170     if (fdMem==-1) {
171                 if ((fdMem = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) {
172                         log->set(OWLOG_ERROR,"No permission to change Port States, try running as root (sudo)");
173                         exit(-1);
174                 }
175         
176                 systReg  = (uint32_t *) mmap(0, SYST_LEN,  PROT_READ|PROT_WRITE|PROT_EXEC,
177                                                                                 MAP_SHARED|MAP_LOCKED,  fdMem, SYST_BASE);
178                 gpioReg  = (uint32_t *) mmap(0, GPIO_LEN,  PROT_READ|PROT_WRITE|PROT_EXEC,
179                                                                                 MAP_SHARED|MAP_LOCKED,  fdMem, GPIO_BASE);
180                 //if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
181                 //else                 *(gpioReg + GPSET0 + BANK) = BIT;
182                 *(gpioReg + GPCLR0 + BANK) = BIT;
183         
184                 gpioReg_read=gpioReg + GPLEV0 + BANK;
185         
186                 gpio_reg=owpin/10;
187                 gpio_shift= (owpin%10) * 3;
188                 gpio_shift_=~(7<<gpio_shift);
189                 gpio_mode_shift=1<<gpio_shift;
190         
191                 BANK=(owpin>>5);
192                 BIT=(1<<(owpin&0x1F));
193         }
194         return 0;       
195         
196 }
197 int owPiGPioInterface::Reset() {
198         int read;
199         OW_SET_LOW;
200         USD(480);
201         OW_RELEASE_LOW;
202         USD(65);
203         read=OW_READ;
204         USD(410);
205         if (read) {
206                 OW_SET_LOW;
207                 USD(480);
208                 OW_RELEASE_LOW;
209                 USD(65);
210                 read=OW_READ;
211                 USD(410);
212
213         }
214         return read==0;
215 }
216
217
218 uint8_t owPiGPioInterface::sendrecivBit(uint8_t bit) {
219         unsigned int lmis;
220         uint8_t read=0;
221         //pinMode(owpin,OUTPUT);
222         lmis=TICK;
223         
224                 //cli_();
225         OW_SET_LOW;
226         lmis+=6;
227         while (TICK<lmis) ;
228         if (bit) {
229                 OW_RELEASE_LOW;
230                 lmis+=11;
231                 while (TICK<lmis) ;
232                 read=OW_READ;
233                 while ((TICK-lmis)<49);
234                 
235         } else {
236                 while ((TICK-lmis)<60);
237                 OW_RELEASE_LOW;
238         }
239         //sti();
240         USD(10);
241         return read;
242 }
243
244
245