SPI.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # COPYRIGHT: Openmoko Inc. 2009
  4. # LICENSE: GPL Version 3 or later
  5. # DESCRIPTION: Simple FLASH programmer
  6. # AUTHOR: Christopher Hall <hsw@openmoko.com>
  7. import sys
  8. import time
  9. import Dump
  10. COMMAND_BOARD_REVISION = 'A'
  11. COMMAND_SPI_WRITE = 'W'
  12. COMMAND_SPI_READ = 'R'
  13. COMMAND_SPI_DESELECT = 'H'
  14. COMMAND_SPI_SELECT= 'L'
  15. def local_len(item):
  16. if str == type(item):
  17. return len(item)
  18. elif list == type(item):
  19. return sum(map(local_len, item))
  20. elif int == type(item):
  21. return 1
  22. return 0
  23. class SPI:
  24. def __init__(self, port):
  25. self.s = port
  26. def version(self):
  27. self.deselect()
  28. self.internal_send(COMMAND_BOARD_REVISION)
  29. time.sleep(0.1)
  30. buffer = self.s.read(2)
  31. rev = ord(buffer[1])
  32. if rev < 5:
  33. return 'A%d' % rev
  34. return 'V%d' % (rev - 4)
  35. def command(self, buffer):
  36. self.select()
  37. self.internal_write(buffer)
  38. self.deselect()
  39. def transact(self, write_buffer, skip_length, read_length):
  40. self.select()
  41. self.internal_write(write_buffer)
  42. self.internal_read(skip_length)
  43. result = self.internal_read(read_length)
  44. self.deselect()
  45. return result
  46. # private functions below here
  47. def select(self):
  48. self.internal_send(COMMAND_SPI_SELECT)
  49. def deselect(self):
  50. self.internal_send(COMMAND_SPI_DESELECT)
  51. def internal_write(self, buffer):
  52. length = local_len(buffer)
  53. if 0 >= length:
  54. return
  55. assert length < 65536, "Write Length: %d too big" % length
  56. self.internal_send([COMMAND_SPI_WRITE, length, (length >> 8), buffer])
  57. def internal_read(self, length):
  58. if 0 >= length:
  59. return
  60. assert length < 65536, "Read Length: %d too big" % length
  61. self.internal_send([COMMAND_SPI_READ, length, length >> 8])
  62. buffer = self.s.read(length)
  63. return buffer
  64. def internal_send(self, item):
  65. if str == type(item):
  66. for c in item:
  67. self.s.write(c)
  68. elif list == type(item):
  69. for x in item:
  70. self.internal_send(x)
  71. elif int == type(item):
  72. self.s.write(chr(item & 0xff))
  73. else:
  74. assert True, 'Invalid send item: %s' % type(item)