accel_clock.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. # Copyright (c) 2023-2024 Victor Suarez Rovere <suarezvictor@gmail.com>
  2. # SPDX-License-Identifier: AGPL-3.0-only
  3. DEBUG = 0 #enable this to run in a unix platform
  4. FRAME_WIDTH = 640
  5. FRAME_HEIGHT = 480
  6. from framebuf import FrameBuffer, RGB32
  7. if DEBUG:
  8. fbuf = FrameBuffer(bytearray(FRAME_WIDTH*FRAME_HEIGHT*4), FRAME_WIDTH, FRAME_HEIGHT, RGB32, FRAME_WIDTH)
  9. else:
  10. import f133 as board #use litex as board for the FPGA board
  11. video = board.Video(0)
  12. fbuf = FrameBuffer(video, video.width(), video.height(), RGB32, video.stride())
  13. video.flush() #makes sure screen gets completely clear
  14. bgcolor = 0xFF0000
  15. fbuf.fill(bgcolor)
  16. fbuf.rect(0, 0, FRAME_WIDTH, FRAME_HEIGHT, 0) #black border
  17. def accel_ellipse_fill(x0, y0, x1, y1, rgba):
  18. global fbuf
  19. cx = (x0 + x1) // 2
  20. cy = (y0 + y1) // 2
  21. w = (x1-x0) // 2
  22. h = (y1-y0) // 2
  23. fbuf.ellipse(cx, cy, w, h, rgba, True)
  24. def accel_rectangle_fill(x0, y0, x1, y1, rgba):
  25. global fbuf
  26. fbuf.fill_rect(x0, y0, x1-x0+1, y1-y0+1, rgba)
  27. def accel_rectangle(x0, y0, x1, y1, rgba):
  28. fbuf.rect(x0, y0, x1-x0+1, y1-y0+1, rgba)
  29. def draw_char(ch, x, y, width, height, rgba):
  30. if ch == ':':
  31. x0 = x+4*width
  32. y0 = y+2*height
  33. accel_ellipse_fill(x0, y0, x0+2*width, y0+4*height, rgba)
  34. y0 += 6*width
  35. accel_ellipse_fill(x0, y0, x0+2*width, y0+4*height, rgba)
  36. return
  37. if ch == '.':
  38. x0 = x+4*width
  39. y0 = y+12*height
  40. accel_ellipse_fill(x0, y0, x0+2*width, y0+2*height, rgba)
  41. return
  42. if ch < '0' or ch > '9':
  43. return
  44. """
  45. 012345
  46. WWWW 0
  47. WW WW 2
  48. WW WW 4
  49. WWWW 6
  50. WW WW 8
  51. WW WW 10
  52. WWWW 12
  53. """
  54. class MaskPos:
  55. def __init__(self, mask, x, y, w, h):
  56. self.mask, self.x, self.y, self.w, self.h = mask, x, y, w, h
  57. segments=[
  58. MaskPos("1011011111", 1, 0, 4, 2), #A (top)
  59. MaskPos("1111100111", 4, 1, 2, 6), #B (top right)
  60. MaskPos("1101111111", 4, 7, 2, 6), #C (bottom right)
  61. MaskPos("1011011011", 1, 12, 4, 2), #D (bottom)
  62. MaskPos("1010001010", 0, 7, 2, 6), #E (bottom left)
  63. MaskPos("1000111011", 0, 1, 2, 6), #F (top left)
  64. MaskPos("0011111011", 1, 6, 4, 2), #G (middle)
  65. ]
  66. chindex = ord(ch)-ord('0')
  67. for i in range(len(segments)):
  68. s = segments[i]
  69. if s.mask[chindex] != '0':
  70. x0 = x+width*s.x
  71. y0 = y+height*s.y
  72. x1 = x0+width*s.w
  73. y1 = y0+height*s.h
  74. if x0 >= 0 and x1 < FRAME_WIDTH and y0 >= 0 and y1 < FRAME_HEIGHT:
  75. accel_rectangle_fill(x0, y0, x1, y1, rgba)
  76. corners=[
  77. MaskPos("1000111011", 0, 0, 2, 2), #top-left
  78. MaskPos("1011000111", 4, 0, 2, 2), #top-right
  79. MaskPos("0010011000", 4, 6, 2, 2), #center-right
  80. MaskPos("1001011011", 4, 12, 2, 2), #bottom-right
  81. MaskPos("1010001010", 0, 12, 2, 2), #bottom-left
  82. MaskPos("0010110001", 0, 6, 2, 2), #center-left
  83. ]
  84. for i in range(len(corners)):
  85. c = corners[i]
  86. if c.mask[chindex] != '0':
  87. x0 = x+width*c.x
  88. y0 = y+height*c.y
  89. x1 = x0+width*c.w
  90. y1 = y0+height*c.h
  91. if x0 >= 0 and x1 < FRAME_WIDTH and y0 >= 0 and y1 < FRAME_HEIGHT:
  92. accel_ellipse_fill(x0, y0, x1, y1, rgba)
  93. #optionally draw some lines around digits
  94. #accel_rectangle(x-2, y-2, x+width*6+2, y+height*15-5, rgba)
  95. def draw_digits(digits, x0, y0, col, sz = 7):
  96. x = x0
  97. y = y0
  98. pos = [0,2,3, 5,7,8, 10,12,13, 15,17]
  99. digits = digits[:len(pos)]
  100. for i, d in enumerate(digits):
  101. x = x0 + pos[i]*4*sz
  102. draw_char(d, x, y, sz, sz, col)
  103. import utime
  104. def get_time():
  105. current_time = utime.localtime(utime.ticks_ms()//1000)
  106. return "{:02d}:{:02d}:{:02d}".format(current_time[3], current_time[4], current_time[5])
  107. prev_time = get_time()
  108. while True:
  109. utime.sleep_ms(100)
  110. current_time = get_time()
  111. if current_time != prev_time:
  112. print("time:", current_time)
  113. draw_digits(prev_time, 100, 100, bgcolor)
  114. draw_digits(current_time, 100, 100, 0x4080FF)
  115. prev_time = current_time
  116. if DEBUG:
  117. if not fbuf.debug_update():
  118. break
  119. else:
  120. video.flush()