gpio_fixup.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #!/usr/bin/python3
  2. # a program to correct the GPIO settings to match the values in the i96 bus spec
  3. #
  4. # Pat Beirne <patb@pbeirne.com> 2021
  5. #
  6. # this script applies only to the OrangePi-i96, booting from u-boot 2012.04.442
  7. from mmap import mmap
  8. import os, sys, time, struct
  9. # assert the i96 GPIO pins into GPIO mode
  10. PORTC_GPIO_MASK = 0 # no pins need changing
  11. PORTA_GPIO_MASK = 0x7e508000 # rda gpioA 15,20,22,25-30 (i96 gpio group)
  12. PORTB_GPIO_MASK = 0 # no pins need changing
  13. PORTD_GPIO_MASK = 0xc # rda gpioD 2,3 (i96 gpioi group)
  14. PORTB_GPIO_MASK_NO_CTSRTS = 0x300 # assert B 8,9 to reuse uart2_cts,rts
  15. # clear the i96 GPIO pins to special function mode
  16. PORTC_SF_MASK = 0xfffffe3f # clear bits C c6,7,8 (i96 uarts)
  17. PORTA_SF_MASK = 0xffff91a0 # clear bits A 0-4,6,9-11,13,14 (i96 i2c, spi, i2s)
  18. PORTB_SF_MASK = 0xfffffc3f # clear bits B 6-9 (i96 i2c, uart)
  19. PORTD_SF_MASK = 0xFFFFFFFF # nothing to change
  20. PORTC_IOMUX = 0x11a09008
  21. PORTA_IOMUX = 0x11a0900c
  22. PORTB_IOMUX = 0x11a09010
  23. PORTD_IOMUX = 0x11a09014
  24. PAGE_MASK = ~0xFFF
  25. PAGE_OFFSET = 0xFFF
  26. # we must read and write 4 bytes at a time, little-endian
  27. def get_word(mapfile, address):
  28. address &= PAGE_OFFSET
  29. return struct.unpack("<L", mapfile[address:address+4])[0]
  30. def put_word(mapfile, address, data):
  31. address &= PAGE_OFFSET
  32. mapfile[address:address+4] = struct.pack("<L",data)
  33. if __name__ == "__main__":
  34. print("OrangePi-i96 fixup GPIO pins")
  35. print("Version 1.0")
  36. try:
  37. with open("/dev/mem","r+b") as m:
  38. mem = mmap(m.fileno(), 32, offset = PORTC_IOMUX & PAGE_MASK)
  39. # set the GPIO pins up (to 1)
  40. put_word(mem, PORTC_IOMUX, get_word(mem, PORTC_IOMUX) | PORTC_GPIO_MASK)
  41. put_word(mem, PORTA_IOMUX, get_word(mem, PORTA_IOMUX) | PORTA_GPIO_MASK)
  42. put_word(mem, PORTB_IOMUX, get_word(mem, PORTB_IOMUX) | PORTB_GPIO_MASK)
  43. put_word(mem, PORTD_IOMUX, get_word(mem, PORTD_IOMUX) | PORTD_GPIO_MASK)
  44. # and set the special function bit down (to 0)
  45. put_word(mem, PORTC_IOMUX, get_word(mem, PORTC_IOMUX) & PORTC_SF_MASK)
  46. put_word(mem, PORTA_IOMUX, get_word(mem, PORTA_IOMUX) & PORTA_SF_MASK)
  47. put_word(mem, PORTB_IOMUX, get_word(mem, PORTB_IOMUX) & PORTB_SF_MASK)
  48. print("GPIO pins corrected to agree with the i96 bus spec")
  49. except PermissionError:
  50. print("failed to open /dev/mem......you must execute this script as root")
  51. exit(2)