libpruw1  0.4
One wire (W1) driver for Beaglebone hardware based on libpruio
pruw1.bas
Go to the documentation of this file.
1 
9 
10 #INCLUDE ONCE "w1_prucode.bi" ' PRU firmware
11 #INCLUDE ONCE "pruw1.hp" ' PRU syncronization
12 #INCLUDE ONCE "BBB/pruio_prussdrv.bi"
13 #INCLUDE ONCE "BBB/pruio_intc.bi"
14 #INCLUDE ONCE "pruw1.bi" ' FB declarations
15 
16 #IFNDEF __PRUW1_MONITOR__
17 
18  #MACRO PRUCALL(_C_,_V_,_T_)
19  WHILE DRam[0] : SLEEP 1 : WEND
20  _V_
21  DRam[0] = _C_ + PruLMod
22  WHILE DRam[0] : SLEEP 1 : WEND
23  #ENDMACRO
24 #ELSE
25 
26  #MACRO PRUCALL(_C_,_V_,_T_)
27  WHILE DRam[0] : SLEEP 1 : ?"."; : WEND
28  _V_
29  DRam[0] = _C_ + PruLMod
30  ?!"\n";_T_; " command=&h"; HEX(DRam[0], 4); " ";
31  WHILE DRam[0] : SLEEP 1 : ?"."; : WEND
32  prot()
33  #ENDMACRO
34 #ENDIF
35 
36 
73 CONSTRUCTOR PruW1(BYVAL P AS PruIo PTR, BYVAL B AS Uint8, BYVAL M AS Uint8 = PRUW1_PULLUP)
74  IF 0 = P ORELSE P->Errr THEN Errr = @"libpruio issue" : EXIT CONSTRUCTOR
75  WITH *P
76  IF B > UBOUND(.BallGpio) THEN _
77  Errr = @"invalid pin number" : EXIT CONSTRUCTOR
78  IF .Gpio->config(B, IIF(M AND PRUW1_PULLUP, PRUIO_GPIO_IN_1, PRUIO_GPIO_IN)) THEN _
79  Errr = @"pin configuration not matching" : EXIT CONSTRUCTOR
80  VAR r = .BallGpio(B) _ ' resulting GPIO (index and bit number)
81  , i = r SHR 5 _ ' index of GPIO
82  , n = r AND 31 _ ' number of bit
83  , ram = PRUSS0_SRAM
84  Mask = 1 SHL n
85  Raw = @.Gpio->Raw(i)->Mix
86  PruLMod = M AND PRUW1_PARPOW
87  IF .PruNo THEN
88  PruNo = 0
89  PruIRam = PRUSS0_PRU0_IRAM
90 #IFNDEF __SRAM_BASE__
91  ram = PRUSS0_PRU0_DRAM
92  ELSE
93  ram = PRUSS0_PRU1_DRAM
94 #ELSE
95  ELSE
96 #ENDIF
97  PruIRam = PRUSS0_PRU1_IRAM
98  PruNo = 1
99  END IF
100  prussdrv_map_prumem(ram, CAST(ANY PTR, @DRam))
101 
102  prussdrv_pru_disable(PruNo) ' disable PRU (if running before)
103  DRam[0] = PruLMod
104  DRam[1] = .Gpio->Conf(i)->DeAd + &h100 ' device adress
105  DRam[2] = Mask ' the mask to related bit
106 
107  VAR l = (UBOUND(Pru_W1) + 1) * SIZEOF(Pru_W1(0))
108  IF 0 >= prussdrv_pru_write_memory(PruIRam, 0, @Pru_W1(0), l) THEN _
109  Errr = @"failed loading PRU firmware" : EXIT CONSTRUCTOR
110  prussdrv_pru_enable(PruNo)
111  IF PruLMod THEN SLEEP 1 ' load capacitors
112  END WITH
113 END CONSTRUCTOR
114 
115 
116 
122 DESTRUCTOR PruW1()
123  prussdrv_pru_disable(PruNo) ' disable PRU
124 END DESTRUCTOR
125 
126 
127 
145 FUNCTION PruW1.scanBus(BYVAL SearchType AS UInt8 = &hF0) AS ZSTRING PTR
146  VAR max_slave = 64 _
147  , cnt = 1 _
148  , desc_bit = 64 _
149  , search_bit = 0 _
150  , last_device = 0 _
151  , last_zero = -1 _
152  , ret = 0 _
153  , rn = 0uLL _
154  , last_rn = rn
155  WHILE 0 = last_device ANDALSO cnt < max_slave
156  last_rn = rn
157  rn = 0
158  IF resetBus() THEN Errr = @"no devices" : RETURN Errr
159  sendByte(SearchType)
160  FOR i AS INTEGER = 0 TO 63
161  SELECT CASE i
162  CASE desc_bit : search_bit = 1 ' took the 0 path last_device time, so take the 1 path
163  CASE IS > desc_bit : search_bit = 0 ' take the 0 path on the next branch
164  CASE ELSE : search_bit = (last_rn SHR i) AND &b1
165  END SELECT
166 
167  PRUCALL(CMD_TRIP + search_bit SHL 8,,"tripple:")
168  ret = DRam[4] AND &b111
169 
170  SELECT CASE AS CONST ret
171  CASE 0 : last_zero = i
172  CASE 3 : CONTINUE WHILE ' should never happen (error -> next device)
173  END SELECT
174  rn OR= CULNGINT(ret) SHR 2 SHL i
175  NEXT
176  IF desc_bit = last_zero ORELSE last_zero < 0 THEN last_device = 1
177  desc_bit = last_zero
178  VAR u = UBOUND(Slots) + 1
179  REDIM PRESERVE Slots(u)
180  Slots(u) = rn
181  cnt += 1
182  WEND : RETURN 0
183 END FUNCTION
184 
185 
186 
194 SUB PruW1.sendByte(BYVAL V AS UInt8)
195  PRUCALL(CMD_SEND + 1 SHL 8,DRam[4] = V,"sendByte: " & HEX(V, 2) & " (&b" & BIN(V, 8) & ")")
196 END SUB
197 
198 
199 
207 SUB PruW1.sendRom(BYVAL V AS ULONGINT)
208  PRUCALL(CMD_SEND + 8 SHL 8,*CAST(ULONGINT PTR, @DRam[4]) = V,"sendRom: " & HEX(PEEK(ULONGINT, @DRam[4]), 16))
209 END SUB
210 
211 
212 
227 FUNCTION PruW1.recvBlock(BYVAL N AS UInt8) AS UInt8
228 #IFDEF __PRUW1_MONITOR__
229  IF N > 112 THEN Errr = @"block too big (< 112 bytes in monitoring)" : RETURN 0
230 #ENDIF
231  PRUCALL(CMD_RECV + N SHL 8,,"recvBlock: " & N)
232  RETURN N
233 END FUNCTION
234 
235 
236 
244 FUNCTION PruW1.recvByte()AS UInt8
245  PRUCALL(CMD_RECV + 1 SHL 8,,"recvByte: ")
246  RETURN DRam[4] AND &hFF
247 END FUNCTION
248 
249 
250 
259 FUNCTION PruW1.getIn() AS UInt8
260  RETURN IIF(*Raw AND Mask, 1, 0)
261 END FUNCTION
262 
263 
264 
275 FUNCTION PruW1.resetBus() AS UInt8
276  PRUCALL(CMD_RESET,,"resetBus:")
277  RETURN DRam[4] AND &b1
278 END FUNCTION
279 
280 
281 
294 FUNCTION PruW1.calcCrc(BYVAL N AS UInt8) AS UInt8
295  VAR crc = 0, p = CAST(UBYTE PTR, @DRam[4])
296  FOR p = p TO p + N - 1
297  crc = Crc8_Table(crc XOR *p)
298  NEXT : RETURN crc
299 END FUNCTION
300 
301 
302 
311 SUB PruW1.prot()
312  STATIC AS UInt32 p = LOG_BASE, b = 0
313  ?
314  FOR i AS INTEGER = 1 TO DRam[3]
315  IF BIT(DRam[p], b) THEN ?"-"; ELSE ?"_";
316  IF 0 = i MOD 70 THEN ?
317  IF b < 31 THEN b += 1 ELSE b = 0 : IF p < 2047 THEN p += 1 ELSE p = LOG_BASE
318  NEXT : ?
319 END SUB
320 
321 
322 
334 FUNCTION PruW1.checkPara()AS UInt8
335  IF resetBus() THEN Errr = @"no devices" : RETURN 0
336  sendByte(&hCC) ' SKIP_ROM command -> broadcast message
337  sendByte(&hB4) ' READ_POWER command
338  RETURN IIF(BIT(recvByte(), 0), 0, 1)
339 END FUNCTION
340 
341 
342 
356 FUNCTION T_fam10(BYVAL Rom AS UBYTE PTR) AS SHORT EXPORT
357  RETURN PEEK(SHORT, Rom) SHR 1 SHL 8 + (Rom[7] - Rom[6] - 4) SHL 4
358 END FUNCTION
359 
360 
361 
376 FUNCTION T_fam20(BYVAL Rom AS UBYTE PTR) AS SHORT EXPORT
377  RETURN PEEK(SHORT, Rom) SHL 4
378 END FUNCTION
379