21 #INCLUDE ONCE "dir.bi"
32 #DEFINE PAGE_SIZE 4096
36 #DEFINE PRU_INTC_GER_REG &h010
38 #DEFINE PRU_INTC_HIEISR_REG &h034
40 #DEFINE PRU_INTC_SRSR0_REG &h200
42 #DEFINE PRU_INTC_SRSR1_REG &h204
44 #DEFINE PRU_INTC_SECR0_REG &h280
46 #DEFINE PRU_INTC_SECR1_REG &h284
48 #DEFINE PRU_INTC_ESR0_REG &h300
50 #DEFINE PRU_INTC_ESR1_REG &h304
52 #DEFINE PRU_INTC_CMR0_REG &h400
54 #DEFINE PRU_INTC_HMR0_REG &h800
56 #DEFINE PRU_INTC_SIPR0_REG &hD00
58 #DEFINE PRU_INTC_SIPR1_REG &hD04
60 #DEFINE PRU_INTC_SITR0_REG &hD80
62 #DEFINE PRU_INTC_SITR1_REG &hD84
65 #DEFINE MAX_HOSTS_SUPPORTED 10
68 #DEFINE PRUSS_UIO_PARAM_VAL_LEN 20
70 #DEFINE KERNEL_PINMUX_PINS
"/sys/kernel/debug/pinctrl/44e10800.pinmux/pinmux-pins"
72 #DEFINE KERNEL_PINMUX_PINX
"/sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pinmux-pins"
81 #DEFINE O_ACCMODE &o003
93 #DEFINE O_NOCTTY &o400
95 #DEFINE O_TRUNC &o1000
97 #DEFINE O_APPEND &o2000
99 #DEFINE O_NONBLOCK &o4000
101 #DEFINE O_NDELAY O_NONBLOCK
103 #DEFINE O_SYNC &o4010000
107 #DEFINE PROT_READ &h1
109 #DEFINE PROT_WRITE &h2
111 #DEFINE PROT_EXEC &h4
113 #DEFINE PROT_NONE &h0
115 #DEFINE PROT_GROWSDOWN &h01000000
117 #DEFINE PROT_GROWSUP &h02000000
120 #DEFINE MAP_SHARED &h01
122 #DEFINE MAP_PRIVATE &h02
125 #DEFINE MAP_TYPE &h0f
138 DECLARE FUNCTION memcpy CDECL ALIAS "memcpy"(
BYVAL AS ANY PTR,
BYVAL AS ANY PTR,
BYVAL AS size_t)
AS ANY PTR
140 DECLARE FUNCTION munmap CDECL ALIAS "munmap"(
BYVAL AS ANY PTR,
BYVAL AS size_t)
AS Int32
142 DECLARE FUNCTION open_ CDECL ALIAS "open"(
BYVAL AS CONST ZSTRING PTR,
BYVAL AS Int32, ...)
AS Int32
159 Intc[(PRU_INTC_CMR0_REG + (Event
AND NOT(&b11)))
SHR 2] _
160 OR= ((Ch
AND &b1111)
SHL ((Event
AND &b11)
SHL 3))
174 Intc[(PRU_INTC_HMR0_REG + (Ch
AND NOT(&b11)))
SHR 2] _
175 = Intc[(PRU_INTC_HMR0_REG + (Ch
AND NOT(&b11)))
SHR 2] _
176 OR (((Host)
AND &b1111)
SHL (((Ch)
AND &b11)
SHL 3))
191 DIM AS STRING*PRUSS_UIO_PARAM_VAL_LEN buff =
""
193 VAR fd =
open_(
"/sys/class/uio/uio0/maps/map0/size", O_RDONLY) :
IF fd < 0
THEN RETURN -11
194 read_(fd, @buff, PRUSS_UIO_PARAM_VAL_LEN)
195 .pruss_map_size =
VALINT(
"&h" +
MID(buff, 3))
198 fd =
open_(
"/sys/class/uio/uio0/maps/map1/addr", O_RDONLY) :
IF fd < 0
THEN RETURN -12
199 read_(fd, @buff, PRUSS_UIO_PARAM_VAL_LEN)
200 .extram_phys_base =
VALINT(
"&h" +
MID(buff, 3))
203 fd =
open_(
"/sys/class/uio/uio0/maps/map1/size", O_RDONLY) :
IF fd < 0
THEN RETURN -13
204 read_(fd, @buff, PRUSS_UIO_PARAM_VAL_LEN)
205 .extram_map_size =
VALINT(
"&h" +
MID(buff, 3))
210 .pru0_dataram_base =
mmap( _
211 0, .pruss_map_size, PROT_READ
OR PROT_WRITE, _
212 MAP_SHARED, .mmap_fd, 0 * PAGE_SIZE)
214 .pru1_dataram_base = .pru0_dataram_base _
215 + .pru1_dataram_phy_base - .pru0_dataram_phy_base
216 .intc_base = .pru0_dataram_base _
217 + .intc_phy_base - .pru0_dataram_phy_base
218 .pru0_control_base = .pru0_dataram_base _
219 + .pru0_control_phy_base - .pru0_dataram_phy_base
220 .pru1_control_base = .pru0_dataram_base _
221 + .pru1_control_phy_base - .pru0_dataram_phy_base
222 .pru0_iram_base = .pru0_dataram_base _
223 + .pru0_iram_phy_base - .pru0_dataram_phy_base
224 .pru1_iram_base = .pru0_dataram_base _
225 + .pru1_iram_phy_base - .pru0_dataram_phy_base
226 .pruss_sharedram_base = .pru0_dataram_base _
227 + .pruss_sram_phy_base - .pru0_dataram_phy_base
229 .extram_base =
mmap( _
230 0, .extram_map_size, PROT_READ
OR PROT_WRITE, _
231 MAP_SHARED, .mmap_fd, 1 * PAGE_SIZE)
251 WITH PRUSSDRV :
IF .fd(Irq)
THEN RETURN -1
253 VAR nam =
"/dev/uio" &
HEX(Irq, 1)
254 .fd(Irq) =
open_(nam, O_RDWR
OR O_SYNC) :
IF .fd(Irq) < 0
THEN RETURN -2
275 IF PCnt > &h1FFC
THEN RETURN -2
276 DIM AS UInt32 v = (((PCnt + 3)
SHR 2)
SHL 16)
OR 2
277 SELECT CASE AS CONST PruId
278 CASE 0 : *
CAST(
UInt32 PTR,
PRUSSDRV.pru0_control_base) = v :
RETURN 0
279 CASE 1 : *
CAST(
UInt32 PTR,
PRUSSDRV.pru1_control_base) = v :
RETURN 0
280 END SELECT :
RETURN -1
293 SELECT CASE AS CONST PruId
294 CASE 0 : *
CAST(
UInt32 PTR,
PRUSSDRV.pru0_control_base) = 1 :
RETURN 0
295 CASE 1 : *
CAST(
UInt32 PTR,
PRUSSDRV.pru1_control_base) = 1 :
RETURN 0
296 END SELECT :
RETURN -1
310 SELECT CASE AS CONST PruId
311 CASE 0 : *
CAST(
UInt32 PTR,
PRUSSDRV.pru0_control_base) = 0 :
RETURN 0
312 CASE 1 : *
CAST(
UInt32 PTR,
PRUSSDRV.pru1_control_base) = 0 :
RETURN 0
313 END SELECT :
RETURN -1
328 SELECT CASE AS CONST PruId
329 CASE 0 : p =
PRUSSDRV.pru0_control_base
330 CASE 1 : p =
PRUSSDRV.pru1_control_base
331 CASE ELSE :
RETURN @
"invalid PRU#"
332 END SELECT :
IF p[0]
AND &h8000
THEN RETURN @
"PRU is running"
333 p[0] = ((1 + p[1])
SHL 16)
OR 2 :
RETURN 0
353 ,
BYVAL Dat
AS CONST UInt32 PTR _
357 SELECT CASE AS CONST RamId
358 CASE PRUSS0_PRU0_DRAM : m =
CAST(
UInt32 PTR,
PRUSSDRV.pru0_dataram_base ) + Offs
359 CASE PRUSS0_PRU1_DRAM : m =
CAST(
UInt32 PTR,
PRUSSDRV.pru1_dataram_base ) + Offs
360 CASE PRUSS0_PRU0_IRAM : m =
CAST(
UInt32 PTR,
PRUSSDRV.pru0_iram_base ) + Offs
361 CASE PRUSS0_PRU1_IRAM : m =
CAST(
UInt32 PTR,
PRUSSDRV.pru1_iram_base ) + Offs
362 CASE PRUSS0_SRAM : m =
CAST(
UInt32 PTR,
PRUSSDRV.pruss_sharedram_base) + Offs
363 CASE ELSE :
RETURN -1
364 END SELECT :
VAR l = (Size + 3)
SHR 2
365 FOR i
AS Int32 = 0
TO l - 1
385 FUNCTION prussdrv_pruintc_init CDECL ALIAS "prussdrv_pruintc_init"(
BYVAL DatIni
AS CONST tpruss_intc_initdata
PTR)
AS Int32 EXPORT
387 VAR intc =
CAST(
UInt32 PTR, .intc_base)
388 DIM AS UInt32 i, mask1, mask2
390 intc[PRU_INTC_SIPR0_REG
SHR 2] = &hFFFFFFFFuL
391 intc[PRU_INTC_SIPR1_REG
SHR 2] = &hFFFFFFFFuL
393 FOR i = 0
TO ((NUM_PRU_SYS_EVTS + 3)
SHR 2) - 1
394 intc[(PRU_INTC_CMR0_REG
SHR 2) + i] = 0
398 WHILE DatIni->sysevt_to_channel_map(i).sysevt <> -1
ANDALSO _
399 DatIni->sysevt_to_channel_map(i).channel <> -1
401 , DatIni->sysevt_to_channel_map(i).sysevt _
402 , DatIni->sysevt_to_channel_map(i).channel)
405 FOR i = 0
TO ((NUM_PRU_HOSTS + 3)
SHR 2) - 1
406 intc[(PRU_INTC_HMR0_REG
SHR 2) + i] = 0
410 WHILE (DatIni->channel_to_host_map(i).channel <> -1)
ANDALSO _
411 (DatIni->channel_to_host_map(i).host <> -1)
413 , DatIni->channel_to_host_map(i).channel _
414 , DatIni->channel_to_host_map(i).host)
418 intc[PRU_INTC_SITR0_REG
SHR 2] = 0
419 intc[PRU_INTC_SITR1_REG
SHR 2] = 0
421 i = 0 : mask1 = 0 : mask2 = 0
422 WHILE DatIni->sysevts_enabled(i) <> -1
423 SELECT CASE DatIni->sysevts_enabled(i)
424 CASE IS < 32 : mask1 = mask1 + (1
SHL (DatIni->sysevts_enabled(i)))
425 CASE IS < 64 : mask2 = mask2 + (1
SHL (DatIni->sysevts_enabled(i) - 32))
426 CASE ELSE :
RETURN -1
430 intc[PRU_INTC_ESR0_REG
SHR 2] = mask1
431 intc[PRU_INTC_SECR0_REG
SHR 2] = mask1
432 intc[PRU_INTC_ESR1_REG
SHR 2] = mask2
433 intc[PRU_INTC_SECR1_REG
SHR 2] = mask2
435 FOR i = 0
TO MAX_HOSTS_SUPPORTED - 1
436 IF DatIni->host_enable_bitmask
AND (1
SHL i) _
437 THEN intc[PRU_INTC_HIEISR_REG
SHR 2] = i
440 intc[PRU_INTC_GER_REG
SHR 2] = &h1
441 memcpy(@.intc_data,
CAST(
ANY PTR, DatIni),
SIZEOF(.intc_data))
456 IF Event < 32
THEN intc[PRU_INTC_SRSR0_REG
SHR 2] = 1
SHL Event _
457 ELSE intc[PRU_INTC_SRSR1_REG
SHR 2] = 1
SHL (Event - 32)
489 IF Event < 32
THEN intc[PRU_INTC_SECR0_REG
SHR 2] = 1
SHL Event _
490 ELSE intc[PRU_INTC_SECR1_REG
SHR 2] = 1
SHL (Event - 32)
491 intc[PRU_INTC_HIEISR_REG
SHR 2] = Irq + 2
503 SUB prussdrv_map_extmem CDECL ALIAS "prussdrv_map_extmem"(
BYVAL Addr
AS ANY PTR PTR)
EXPORT
536 SELECT CASE AS CONST RamId
537 CASE PRUSS0_PRU0_DRAM : *Addr =
PRUSSDRV.pru0_dataram_base :
RETURN 0
538 CASE PRUSS0_PRU1_DRAM : *Addr =
PRUSSDRV.pru1_dataram_base :
RETURN 0
539 CASE PRUSS0_PRU0_IRAM : *Addr =
PRUSSDRV.pru0_iram_base :
RETURN 0
540 CASE PRUSS0_PRU1_IRAM : *Addr =
PRUSSDRV.pru1_iram_base :
RETURN 0
541 CASE PRUSS0_SRAM : *Addr =
PRUSSDRV.pruss_sharedram_base :
RETURN 0
542 END SELECT : *Addr = 0 :
RETURN -1
559 CASE .pru0_dataram_base
TO .pru0_dataram_base + .pruss_map_size - 1
560 RETURN CAST(
UInt32, Addr - .pru0_dataram_base) + .pru0_dataram_phy_base
561 CASE .extram_base
TO .extram_base + .extram_map_size - 1
562 RETURN CAST(
UInt32, Addr - .extram_base) + .extram_phys_base
563 END SELECT :
RETURN 0
578 munmap(.pru0_dataram_base, .pruss_map_size)
579 munmap(.extram_base, .extram_map_size)
580 FOR i
AS LONG = 0
TO NUM_PRU_HOSTIRQS - 1
581 IF .fd(i)
THEN close_(.fd(i)) : .fd(i) = 0
600 #DEFINE TBUFF_SIZE 32768
602 DIM AS STRING*TBUFF_SIZE t
603 VAR fd =
open_(KERNEL_PINMUX_PINS, O_RDONLY)
605 fd =
open_(KERNEL_PINMUX_PINX, O_RDONLY) :
IF fd < 0
THEN RETURN 0
606 VAR r =
read_(fd, @t, TBUFF_SIZE)
608 VAR toffs = (PRUIO_AZ_BALL + 1)
SHL 1
609 mux =
STRING(toffs, 0) &
"internal CPU ball" &
CHR(0)
610 VAR x =
"", m =
CAST(Int16
PTR,
SADD(mux))
611 FOR i
AS INTEGER = 0
TO PRUIO_AZ_BALL : m[i] = toffs :
NEXT
612 SELECT CASE AS CONST Typ
613 CASE PBB2x36 : x = HEADERPINS_POCKET
614 CASE BB_Blue : x = HEADERPINS_BLUE
615 CASE ELSE : x = HEADERPINS_BB
616 END SELECT :
FOR i
AS INTEGER = 0
TO LEN(x) - 1 : m[x[i]] = 0 :
NEXT
618 VAR p =
CAST(
ZSTRING PTR,
SADD(t) + 3) _
620 , a = 1, e =
INSTR(t, !
"\n")
622 IF *
CAST(
Int32 PTR, p + a - 4) = c
THEN
623 VAR n =
VALINT(*(p + a)) :
IF n > PRUIO_AZ_BALL
THEN EXIT WHILE
624 VAR p1 =
INSTR(a, t,
"): ") + 3
626 IF t[p1 - 1] <>
ASC(
"(")
THEN
627 VAR p2 =
INSTR(p1, t,
" ") _
628 , own =
MID(t, p1,
IIF(p2, p2, e) - p1) &
CHR(0) _
629 , x =
INSTRREV(mux,
CHR(0) & own)
630 IF x < toffs
THEN x =
LEN(mux) : mux &= own
631 CAST(Int16
PTR,
SADD(mux))[n] = x
634 END IF : a = e + 1 : e =
INSTR(a, t, !
"\n")
635 WEND :
RETURN SADD(mux)
666 BYVAL Top
AS Pruio_
PTR _
667 ,
BYVAL Ball
AS UInt8 _
668 ,
BYVAL Mo
AS UInt8)
AS ZSTRING PTR
670 IF Ball > PRUIO_AZ_BALL
THEN .Errr = @
"unknown ball number" :
RETURN .Errr
672 VAR m =
IIF(Mo = PRUIO_PIN_RESET, .BallInit[Ball], Mo)
674 CASE .BallConf[Ball] :
RETURN 0
675 CASE .BallInit[Ball] :
IF 24 = (.BallConf[Ball]
AND 24)
THEN RETURN 0
677 PUT #.MuxFnr, ,
HEX((Ball
SHL 8) + (m
AND &b1111111), 4)
678 SEEK #.MuxFnr, 1 : .BallConf[Ball] = m :
RETURN 0
701 BYVAL Top
AS Pruio_
PTR _
702 ,
BYVAL Ball
AS UInt8 _
703 ,
BYVAL Mo
AS UInt8)
AS ZSTRING PTR
707 SELECT CASE AS CONST Ball
713 END SELECT : r = .BallGpio(b)
716 .Mode = PRUIO_GPIO_IN_0
717 .Mask = 1
SHL (r
AND 31)
720 VAR m =
IIF(Mo = PRUIO_PIN_RESET, .BallInit[Ball], Mo)
722 CASE .BallConf[Ball] :
RETURN 0
723 CASE .BallInit[Ball] :
IF 24 = (.BallConf[Ball]
AND 24)
THEN RETURN 0
726 PUT #.MuxFnr, ,
HEX( b, 2) &
"27" _
727 &
HEX(Ball, 2) &
HEX(m
AND &b1111111, 2)
729 .BallConf[b] = PRUIO_GPIO_IN_0 : .BallConf[Ball] = m :
RETURN 0
753 BYVAL Top
AS Pruio_
PTR _
754 ,
BYVAL Ball
AS UInt8,
BYVAL Mo
AS UInt8)
AS ZSTRING PTR
755 STATIC AS ZSTRING PTR m
756 STATIC set_func
AS setPinFunc
760 IF 0 = m
ORELSE Ball > PRUIO_AZ_BALL
THEN
763 .Errr =
IIF(m, 0, @
"parsing kernel claims") :
RETURN .Errr
766 VAR o =
CAST(Int16
PTR, m) :
IF 0 = o[Ball]
THEN RETURN set_func(Top, Ball, Mo)
768 IF x
THEN e =
"pin " & *x
ELSE e =
"ball" & Ball
769 e &=
" claimed by: " & *(m + o[Ball]) : .Errr =
SADD(e) :
RETURN .Errr
790 BYVAL Top
AS Pruio_
PTR _
791 ,
BYVAL Ball
AS UInt8 _
792 ,
BYVAL Mo
AS UInt8)
AS ZSTRING PTR
794 Top->Errr = @
"pinmux missing" :
RETURN Top->Errr
819 BYVAL Top
AS Pruio_
PTR _
820 ,
BYVAL Ball
AS UInt8 _
821 ,
BYVAL Mo
AS UInt8)
AS ZSTRING PTR
823 IF Ball > PRUIO_AZ_BALL
THEN _
824 .Errr = @
"unknown setPin ball number" :
RETURN .Errr
826 VAR m =
IIF(Mo = PRUIO_PIN_RESET, .BallInit[Ball], Mo)
827 IF .BallConf[Ball] = m
THEN RETURN 0
829 SELECT CASE AS CONST .MuxFnr
831 VAR fnam = *.MuxAcc &
HEX(Ball, 2)
832 VAR p =
DIR(fnam &
".*", fbDirectory)
833 fnam &=
MID(p,
INSTR(p,
"."))
835 IF OPEN(fnam &
"/state" FOR OUTPUT AS fnr)
THEN EXIT SELECT
836 PRINT #fnr,
"x" &
HEX(m, 2)
837 CLOSE #fnr : .BallConf[Ball] = m :
RETURN 0
839 VAR fnam = *.MuxAcc &
HEX(Ball, 2), fnr =
FREEFILE
840 IF OPEN(fnam &
"/state" FOR OUTPUT AS fnr)
THEN EXIT SELECT
841 PRINT #fnr,
"x" &
HEX(m, 2)
842 CLOSE #fnr : .BallConf[Ball] = m :
RETURN 0
843 CASE ELSE : .Errr = @
"no ocp access" :
RETURN .Errr
846 STATIC AS STRING*30 e =
"pinmux failed: P._.. -> x.."
848 IF x
THEN MID(e, 16, 5) = *x
ELSE MID(e, 16, 5) =
"bal" &
HEX(Ball, 2)
849 MID(e, 26, 2) =
HEX(m, 2) : .Errr =
SADD(e) :
RETURN .Errr