import time
time.sleep(0.1) # Wait for USB to become ready
print("Hello, Pi Pico!")
#-------------------------------------------------------
#-------------------------------------------------------
import rp2
from machine import Pin, PWM
import utime
import math
import sys
# Define key and LED pins
KEY1 = Pin(0, Pin.IN, Pin.PULL_UP)
KEY2 = Pin(1, Pin.IN, Pin.PULL_UP) # KEY2 for turning backlight ON/OF
# 割り込みフラグ
falling_edge_flag = False
rising_edge_flag = False
# 立下りエッジの処理
def button_falling_handler(pin):
global falling_edge_flag
falling_edge_flag = True # 立下りエッジのフラグを設定
# 立上りエッジの処理
def button_rising_handler(pin):
global rising_edge_flag
rising_edge_flag = True # 立上りエッジのフラグを設定
# 割り込みの設定
#KEY2.irq(trigger=Pin.IRQ_FALLING, handler=button_falling_handler) # 立下りエッジ
#KEY2.irq(trigger=Pin.IRQ_RISING, handler=button_rising_handler) # 立上りエッジ
# 立下りエッジの処理
def button_handler(pin):
global falling_edge_flag
global rising_edge_flag
utime.sleep_ms(20) # 50msの遅延
if KEY2.value() == 0: # スイッチが押されているか確認
falling_edge_flag = True # 立下りエッジのフラグを設定
elif KEY2.value() == 1: # スイッチが離されているか確認
rising_edge_flag = True # 立上りエッジのフラグを設定
# 割り込みの設定
KEY2.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=button_handler) # 両エッジ
led_pin = Pin(25, Pin.OUT)
#led_state = False
Vddio = Pin(4, mode=Pin.OUT, value=0)
Vddio_2 = Pin(3, mode=Pin.OUT, value=1)
Vled = Pin(5, mode=Pin.OUT, value=0)
status_pin = Pin(18, mode=Pin.OUT, value=0) # 使用目的は?
cs_pin = Pin(13, mode=Pin.OUT, value=0)
pwm = Pin(9, mode=Pin.OUT, value=0)
status = 0 # Initialize status to 0 # line785と重複、意図は?
loop_count = 0 # Initialize loop counter # 使用していません!変数の意図は?
button_press_count = 0 # 使用していません!変数の意図は?
t1_us = 50 # 100 us; make sure all sclk are sent before SCS is setted High level
#the time from VLED low to VDD low is t2_s(VLED low to CS low,1ms) + t3_s(CS low to VDD low,50ms), it's setted 51ms
t2_ms = 1 # 1ms
t3_ms = 50 # the time from the discharge of vled to vddio
# adjust data from 8 bit to 32 bit, if you want the data to be sent in units of 8 bits, the number here should be changed to 8.
# 8 bit → 8; 16 bit → 16; 24 bit → 24; 32 bit → 32;
#The reason for sending data in 32-bit units is that it is easier to understand and the most efficient way to send the total write_blocking data.
#On the other hand, if data is sent in 8-bit/6-bit/24-bit units, there will be losses in the SCK waveform.
get_threshold = 32
# Shift the data ___bit to the left, if you want the data to be sent in units of 8 bits, the number here should be changed to 24.
# 32 bit → 0; 24 bit → 8; 16 bit → 16; 8 bit → 24;
get_shift_value = 0
loop_time = 1 # set loop 1 time # 使用していません!変数の意図は?
delay_in_seconds = 1 * 600 # set 10000 hours (during LED on) → 10000* 3600(10000→10000 times, 3600→3600s/1H), one second longer # 使用していません!変数の意図は?
led_off_delay = 5 # set 5 s (during LED off) # 使用していません!変数の意図は?
duty_value_1 = 33 # 33% → 33
duty_value_2 = 40 # 40% → 40
duty_value_100 = 110 # 100% → 110
duty_value_10 = 10 # 10% → 10
duty_value_11_9 = 11.9 # 11.9% → 11.9
vsy_freq = 60
osc_freq = 4000000 # oscillator frequency(P1→3333333[3.33MHz],period→300ns:period; P2→4000000[4MHz], period→250ns)
time_res = 2 # time resolution(P1=1, P2=2)
#Sends data in units of 4
chunk_size = 4 # 8 bit → 1; 16 bit → 2; 24 bit → 3; 32 bit → 4;
SPECIAL_VALUE = [0xC8, 0x85] # 使用していません!リスト化の意図は?
# Setting the Threshold of VC
SLDET_1 = 0x40 # 0xC0(7.5V), 0x80(4.65V), 0x40(2.5V), 0x00(2.0V)
SLDET_2 = 0x00 # 0xC0(7.5V), 0x80(4.65V), 0x40(2.5V), 0x00(2.0V)
board_type = "Unknown"
def combine_hex_elements(lst, chunk_size):
add_len = chunk_size - (len(lst) % chunk_size)
lst.extend([0] * add_len)
result = []
for i in range(0, len(lst), chunk_size):
combined = 0
for byte in lst[i:i + chunk_size]:
combined = (combined << 8) | byte
result.append(combined)
return result
def write_blocking_pwm(adr_header, duty):
pwm_dec = math.ceil(duty / 100 * osc_freq / time_res / vsy_freq) # 切り上げ
# pwmdata = [pwm_dec // 256, pwm_dec % 256]
pwmdata = [pwm_dec >> 8, pwm_dec & 255] # 動作確後どちらが良いか判断して下さい。
adr_header.extend(pwmdata * 38)
wdata = combine_hex_elements(adr_header + filler, chunk_size)
pio_spi.write_blocking(wdata)
utime.sleep_ms(32)
def iLED(att3,att2,att1):
att3 = att3 - 69 if att3 > 69 else 0
att2 = att2 - 69 if att2 > 69 else 0
att1 = att1 - 69 if att1 > 69 else 0
att = ((((att3 << 5) + att2) << 5) + att1)
iLEDnH = att >> 8
iLEDnL = att & 255
return (iLEDnH, iLEDnL)
# Define PIO program
@rp2.asm_pio(
out_shiftdir=0,
in_shiftdir=0, #PIO.SHIFT_LEFT,
autopull=True,
pull_thresh=get_threshold, #8,
autopush=True,
push_thresh=get_threshold, #8,
sideset_init=(rp2.PIO.OUT_LOW),
out_init=rp2.PIO.OUT_LOW)
def spi_cpha0():
set(x, 6)
wrap_target()
pull(ifempty) .side(0x0) [1]
label("bitloop")
out(pins, 1) .side(0x0) [1] # Control MOSI high and low levels here
in_(pins, 1) .side(0x1)
jmp(x_dec, "bitloop") .side(0x1)
out(pins, 1) .side(0x0)
set(x, 6) .side(0x0)
in_(pins, 1) .side(0x1)
jmp(not_osre, "bitloop") .side(0x1)
# nop() .side(0x0) [1]
wrap()
class PIOSPI:
# def __init__(self, sm_id, pin_mosi, pin_miso, pin_sck, cs_pin, cpha=False, cpol=False, freq=2000000):
def __init__(self, sm_id, pin_mosi, pin_miso, pin_sck, cpha=False, cpol=False, freq=2000000):
assert(not(cpol or cpha))
# self._sm = rp2.StateMachine(sm_id, spi_cpha0, freq=4*freq,
# sideset_base=Pin(cs_pin),
# out_base=Pin(pin_mosi),
# in_base=Pin(pin_miso),
# set_base=Pin(pin_mosi))
self._sm = rp2.StateMachine(sm_id, spi_cpha0, freq=4*freq,
sideset_base=Pin(pin_sck),
out_base=Pin(pin_mosi),
in_base=Pin(pin_miso))
MISO = Pin(pin_miso, Pin.IN)
# self._sm.active(1)
# self._cs = Pin(cs_pin, Pin.OUT)
# The CS here is defined by the PIO as pin 9, but actually the CS is defined and used by the GPIO as pin 13;Because VSYNC (#9) in the GPIO is signaling suspiciously once before KEY1 is pressed, to fix this one bug, I'll use the PIO to pull cs low
# self._cs.value(0) # Initialize CS to low level(vsync level will )
self._sm.active(1)
# def write_read_blocking(self, wdata):
# cs_pin.value(0)
# rwbit=(wdata[0]>>23) & 0x0001
# rdata = []
# if rwbit==1:
# for b in wdata:
# self._sm.put(b << get_shift_value)
# rdata.append(self._sm.get())
# else:
# for b in wdata:
# self._sm.put(b << get_shift_value)
# self._sm.get()
# utime.sleep_us(t1_us)
# cs_pin.value(1)
# return rdata
def write_read_blocking(self, wdata):
cs_pin.value(0)
rdata = []
for b in wdata:
self._sm.put(b << get_shift_value)
rdata.append(self._sm.get())
utime.sleep_us(t1_us)
cs_pin.value(1)
return rdata
def write_blocking(self, wdata):
cs_pin.value(0)
# self._sm.restart()
for b in wdata:
self._sm.put(b << get_shift_value)
self._sm.get() # dummy
utime.sleep_us(t1_us)
cs_pin.value(1)
# utime.sleep_ms(1)
# def read_blocking(self, n):
# self.start()
# data = []
# for i in range(n):
# data.append(self._sm.get() & 0x4F)
# self.close()
# return data
# Initialize PIO SPI
#pio_spi = PIOSPI(0, 11, 19, 10, 9) # 0→sm_id,11→MOSI,19→MISO,10→SCK,9→CS(Not used)
pio_spi = PIOSPI(0, 11, 12, 10) # 0→sm_id,11→MOSI,12→MISO,10→SCK,13→CS(Not used)
# filler Data
#filler_byte =[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, # filler byte #1~8
# 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, # filler byte #9~16
# 0x00,0x00,0x00,0x00,0x00] # filler byte #17~21(devices-1)
#filler = filler_byte[0:23]
filler = [0x00] * 22 # filler byte:(devices-1)
# SW_RESET (0x24)
sw_reset = [0x3E, 0x01, 0x24, # Broadast(Write with Same data) 1 address from 0x24(SW_RESET)
0x80, 0x00 # In Page 51 of datasheet, , 0x8000 is set to enable SW_RESET (1) in the CNFG_SYS2 (0x24).
]
#sw_reset = sw_reset[0:7] + filler
sw_reset.extend(filler)
res_data = combine_hex_elements(sw_reset, chunk_size)
# Device Enumeration/Auto-Addressing
dev_enum = [0xC0, 0x01, 0x07, 0x16] # 'Enumeration in a 22-Device System' setting in Page 18
dev_enum.extend(filler)
enumeration_data = combine_hex_elements(dev_enum, chunk_size)
# CNFG_SYS1(R23h), CNFG_SYS2(R24h), CNFG_MASK(R25h)
set23_25 = [0x3E, 0x03, 0x23, # Broadast(Write with Same data) 3 address from 0x23 to 0x25
0x00, 0x88, # 0x23=0x0088, FPSFT_ENABLE(bit 6) in 0x88 should be disable(set bit 6→0) first, FPSFT_SET(bit 5:4) should be set 0x0 (default value)
0x00, 0x03, # 0x24=0x0003 in the right side means change to 8 scan (SCAN sets are in page 52 of datasheet);SNK_ delay settings in page 51 & 52 of datasheet, DELAY OPTION(1:0)→0x0: 8μs per LSb; 0x1: Minimum pulse width 500ns
0x00, 0xC7 # 0x25=0x00C7→enable all the functions in page 52 of the datasheet.
]
set23_25.extend(filler)
s23_25 = combine_hex_elements(set23_25, chunk_size)
# SNKSET_1(R29h)
SLdet_1 = [ 0x3E, 0x01, 0x29, # Broadast(Write with Same data) 1 address from 0x29(SNKSET)
SLDET_1, 0x00] # threshold of VC, [15:14]SLDET=1(2.5V)
SLdet_1.extend(filler)
R29h_SLDET_1 = combine_hex_elements(SLdet_1, chunk_size)
# SNKSET_2(R29h)
SLdet_2 = [ 0x3E, 0x01, 0x29, # Broadast(Write with Same data) 1 address from 0x29(SNKSET)
SLDET_2, 0x00] # threshold of VC, [15:14]SLDET=0(2.0V)
SLdet_2.extend(filler)
R29h_SLDET_2 = combine_hex_elements(SLdet_2, chunk_size)
# CNFG_ILED(R17h)
set_17 = [ 0x3E, 0x01, 0x17, # Broadast(Write with Same data) 1 address from 0x17(CNFG ILED)
0x02, 0x20 # default 0x17 = 0x0220(peak current:10mA); 0x020C(peak current:5mA)
]
set_17.extend(filler)
s17 = combine_hex_elements(set_17, chunk_size)
# DISABLE1_16(R14h)
set_14 = [ 0x3F, 0x01, 0x14, # Broadast(Write with Different Data) 1 address from 0x14(DISABLE1_16)
0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,# Dev#1~7; enable SNK16~1
0x00,0x02, 0x00,0x02, 0x00,0x02, # Dev#8~10; disable SNK2 (DISABLE1_16 (0x14) in page 38 of the datasheet)
0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, # Dev#11~16; enable SNK16~1
0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00 # Dev#17~22; enable SNK16~1
]
set_14.extend(filler)
s14 = combine_hex_elements(set_14, chunk_size)
set_16 = [ 0x3F, 0x01, 0x16, # Broadast(Write with Different Data) 1 address from 0x16(DISABLE33_38)
0x00,0x20, 0x00,0x20, 0x00,0x20, 0x00,0x20, 0x00,0x20, 0x00,0x20, # Dev#1~6; disable SNK38 (DISABLE33_38 (0x16) in page 38 of the datasheet)
0x00,0x20, 0x00,0x20, 0x00,0x20, 0x00,0x20, 0x00,0x20, 0x00,0x20, # Dev#7~12; disable SNK38 (DISABLE33_38 (0x16) in page 38 of the datasheet)
0x00,0x00, 0x00,0x00, 0x00,0x00, # Dev#13~15; enable SNK38~33
0x00,0x20, 0x00,0x20, # Dev#16~17; disable SNK38
0x00,0x00, # Dev#18; enable SNK38~33
0x00,0x20, # Dev#19; disable SNK38
0x00,0x00, # Dev#20; enable SNK38~33
0x00,0x20, # Dev#21; disable SNK38
0x00,0x00 # Dev#22; enable SNK38~33
]
set_16.extend(filler)
s16 = combine_hex_elements(set_16, chunk_size)
set_ILEDn = [ 0x3E, 0x0D, 0x2B, # Broadast(Write with Same data) 13 address from 0x2B to 0x37(ILEDn)
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x2B=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x2C=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x2D=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x2E=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x2F=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x30=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x31=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x32=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x33=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x34=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x35=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED(84,84,84)[0], iLED(84,84,84)[1], # 0x36=0x3DEF; 3DEF→putted three 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
iLED( 0,84,84)[0], iLED( 0,84,84)[1], # 0x37=0x01EF; 01EF→putted two 0x0F(Individual Channel Current Settings in p13 of the datasheet) together according to ILED3_1 (0x2B) on page 56
] # Because it only has 10 bits in ILED38_37 (0x37) on page 63 of the datasheet
set_ILEDn.extend(filler)
ILEDn = combine_hex_elements(set_ILEDn, chunk_size)
GBL_PWM = [ 0x3E, 0x01, 0x74, # Broadast(Write with Same data) 1 address from 0x74(GBL_PWM_LOW16_VWDPORT)
0x00, 0x00 # 0% (change to 0x0000 from 0x1388(default))
]
GBL_PWM.extend(filler)
GBL_PWM0 = combine_hex_elements(GBL_PWM, chunk_size)
delay = [ 0x3E, 0x0D, 0x66, # Broadast(Write with Same data) 13 address from 0x66~0x72(DELAY)
0x08, 0x20, # 0x66=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x14, 0x83, # 0x67=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x20, 0xE6, # 0x68=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x2D, 0x49, # 0x69=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x39, 0xAC, # 0x6A=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x46, 0x0F, # 0x6B=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x04, 0x12, # 0x6C=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x10, 0x62, # 0x6D=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x1C, 0xC5, # 0x6E=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x29, 0x28, # 0x6F=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x35, 0x8B, # 0x70=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x41, 0xEE, # 0x71=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
0x02, 0x51 # 0x72=0x0000 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
# 0x00 = 0(hex, delay 0:0us) ; 0x20 = 1(hex, delay 1:8us) ;
# 0x40 = 2(hex, delay 2:16us); 0x60 = 3(hex, delay 3:24us);
# 0x80 = 4(hex, delay 4:32us); 0xA0 = 5(hex, delay 5:40us);
# 0xC0 = 6(hex, delay 6:48us); 0xA0 = 7(hex, delay 7:56us);
]
delay.extend(filler)
set_delay = combine_hex_elements(delay, chunk_size)
# DEV_ID (0x00) Read
#Dev_ID = [0x3F, 0x81, 0x00] # Broadast(Write with Same data) 1 address from 0x00(Dev_ID)
#Dev_ID.extend([0x00, 0x00] * 1 * 22)
Dev_ID = [0x3F, 0x81, 0x00, # Broadast(Read data) 1 address from 0x00(DEV_ID)
0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,
0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,
0x00,0x00, 0x00,0x00, 0x00,0x00,
0x00,0x40, 0x01,0x40, 0x02,0x40, 0x03,0x40, # Dev# 1~ 4;
0x04,0x40, 0x05,0x40, 0x06,0x40, 0x07,0x40, # Dev# 5~ 8;
0x08,0x40, 0x09,0x40, 0x0A,0x40, 0x0B,0x40, # Dev# 9~12;
0x0C,0x40, 0x0D,0x40, 0x0E,0x40, 0x0F,0x40, # Dev#13~16;
0x10,0x40, 0x11,0x40, 0x12,0x40, 0x13,0x40, # Dev#17~20;
0x14,0x40, 0x15,0x40 # Dev#21~24;
]
#Dev_ID.extend(filler)
Dev_Ver = combine_hex_elements(Dev_ID, chunk_size)
def check_board_version(useful_data, device_count=22):
# 各デバイスのデータから第2バイトのみを抽出(2バイトごとに1個スキップしながら)
# 例:useful_data[1], useful_data[3], useful_data[5], ... と取り出す(合計device_count個)
second_bytes = useful_data[1:device_count*2:2]
Led_board_is_p2 = True # 最初は全デバイスが「P2ボード」と仮定
for i, byte in enumerate(second_bytes): # second_bytes の中のすべてのデータを1つずつ取り出して、そのときの番号(index)も一緒に取り出すため
bin_str = "{:08b}".format(byte) # byte(整数)を8桁の2進数に変換(例:0x3A → "00111010")
print(f"Device {i+1}: 0x{byte:02X} -> {bin_str}")
bit7 = (byte >> 7) & 1
bit6 = (byte >> 6) & 1
bit5 = (byte >> 5) & 1
version_bits = f"{bit7}{bit6}{bit5}"
print(f"Device {i+1} version bits: {version_bits}")
rev_id = (byte >> 5) & 7
print(rev_id)
if version_bits == "000":
print(f"Critical error: Device {i+1} version bits is '000'. Aborting program.")
raise SystemExit("Version bits '000' detected, aborting.") # プログラムを終了
if version_bits != "010": # 「010」以外がある場合は、P2ボードではないと判断
Led_board_is_p2 = False
board_type = "P2" if Led_board_is_p2 else "Not P2"
print(f"Board Type: {board_type}")
return board_type # 判定結果を返す
def get_board_type_from_raw(raw_data):
split_data = split_rd_data(raw_data)
useful_data = split_data[25:]
print("MISO Response (filtered):", useful_data)
board_type = check_board_version(useful_data)
return board_type
# BIST_REG(R18h)
# Bist ON
BistOn = [0x3E, 0x01, 0x18, # Broadast(Write with Same data) 1 address from 0x18(BIST_REG)
0x00, 0x03] # [2]BIST_CURR=0(10uA), [1]BIST_ODD=1(Enable), [0]BIST_EVEN=1(Enable)
BistOn.extend(filler)
BIST_ON = combine_hex_elements(BistOn, chunk_size)
BistOn_odd = [0x3E, 0x01, 0x18, # Broadast(Write with Same data) 1 address from 0x18(BIST_REG)
0x00, 0x02] # [2]BIST_CURR=0(10uA), [1]BIST_ODD=1(Enable), [0]BIST_EVEN=0(disable)
BistOn_odd.extend(filler)
BIST_ON_odd = combine_hex_elements(BistOn_odd, chunk_size)
BistOn_even = [0x3E, 0x01, 0x18, # Broadast(Write with Same data) 1 address from 0x18(BIST_REG)
0x00, 0x01] # [2]BIST_CURR=0(10uA), [1]BIST_ODD=0(disable), [0]BIST_EVEN=1(Enable)
BistOn_even.extend(filler)
BIST_ON_even = combine_hex_elements(BistOn_even, chunk_size)
# Bist OFF
BistOff = [0x3E, 0x01, 0x18, # Broadast(Write with Same data) 1 address from 0x18(BIST_REG)
0x00, 0x00] # [2]BIST_CURR=0(10uA), [1]BIST_ODD=0(Disable), [0]BIST_EVEN=0(Disable)
BistOff.extend(filler)
BIST_OFF = combine_hex_elements(BistOff, chunk_size)
# BIST1_38(R19h~R1Bh) Read
BistRead = [0x3F, 0x83, 0x19] # Broadast(Read with Different Data) 3 address from 0x19~0x1B(BIST1_38)
BistRead.extend([0x00, 0x00] * 3 * 22) # 3 address 22 device
BistRead.extend(filler)
BIST_RD = combine_hex_elements(BistRead, chunk_size)
#EN 1(Switch Go)
en_1 = [0x3E, 0x01, 0x26, # Broadast(Write with Same data) 13 address from 0x26(Switch Go)
0x80, 0x00 # EN=1
]
en_1.extend(filler)
e1 = combine_hex_elements(en_1, chunk_size)
en_0 = [0x3E, 0x01, 0x26, # Broadast(Write with Same data) 13 address from 0x26(Switch Go)
0x00, 0x00 # EN=0
]
en_0.extend(filler)
e0 = combine_hex_elements(en_0, chunk_size)
def init_AOI_full_lighting(): # Initial settings configured to enable full lighting for AOI inspection.
global board_type
led_pin.value(1)
Vddio.value(1)
#Vddio_2.value(0)
utime.sleep_ms(10)
cs_pin.value(1)
utime.sleep_ms(1)
#pwm.duty_u16(int(65535 * 0.01)) # Send PWM signal, set duty cycle to 1%
#utime.sleep_ms(20)
Vled.value(1)
utime.sleep_ms(1)
pio_spi.write_blocking(res_data) # Send reset_data
utime.sleep_ms(10)
pio_spi.write_blocking(enumeration_data)
#pio_spi.write_read_blocking(Dev_Ver)
#print(Dev_data)
pio_spi.write_blocking(s23_25)
#pio_spi.write_blocking(R29h_SLDET_1) # ShortLED detect for BIST
pio_spi.write_blocking(s17) # 5mA
pio_spi.write_blocking(s14)
pio_spi.write_blocking(s16)
pio_spi.write_blocking(ILEDn) # 84%=> 5mA*84%=4.2mA
pio_spi.write_blocking(set_delay)
pio_spi.write_blocking(GBL_PWM0) # duty 0%
#board_type = get_board_type_from_raw(raw_data)
# if global_board_type != "P2":
# print("Non-P2 board detected, terminating program.")
# raise SystemExit("Non-P2 board, exit.")
#
# print("P2 board detected, running change_pwm_aligned_skip_lighting()")
# change_pwm_aligned_skip_lighting()
def judge_LED_board():
global board_type
led_pin.value(1)
#Vddio.value(1)
##Vddio_2.value(0)
#utime.sleep_ms(10)
#cs_pin.value(1)
#utime.sleep_ms(1)
##pwm.duty_u16(int(65535 * 0.01)) # Send PWM signal, set duty cycle to 1%
##utime.sleep_ms(20)
#Vled.value(1)
#utime.sleep_ms(1)
#pio_spi.write_blocking(res_data) # Send reset_data
#utime.sleep_ms(10)
#pio_spi.write_blocking(enumeration_data)
#pio_spi.write_blocking(s23_25)
#pio_spi.write_blocking(R29h_SLDET_1) # ShortLED detect for BIST
raw_data = pio_spi.write_read_blocking(Dev_Ver)
board_type = get_board_type_from_raw(raw_data)
if board_type == "P2":
print("P2 board detected - using aligned skip lighting")
#change_pwm_aligned_skip_lighting()
#pio_spi.write_blocking(e1)
#print("Executing change_pwm_aligned_skip_lighting()")
utime.sleep_ms(1000)
#Bist_odd_2_5V()
#print('odd LED pattern')
#Bist_even_2_5V()
#print('even LED pattern')
#Bist_odd_2_0V()
#print('odd LED pattern')
#Bist_even_2_0V()
#print('even LED pattern')
else:
print("Not P2 board")
raise SystemExit("Only P2 boards supported.")
#status = 0 # 状態を status = 0 にする
def Bist_testing():
led_pin.value(1)
Vddio.value(1)
#Vddio_2.value(0)
utime.sleep_ms(10)
cs_pin.value(1)
utime.sleep_ms(1)
#pwm.duty_u16(int(65535 * 0.01)) # Send PWM signal, set duty cycle to 1%
#utime.sleep_ms(20)
Vled.value(1)
utime.sleep_ms(1)
pio_spi.write_blocking(res_data) # Send reset_data
utime.sleep_ms(10)
pio_spi.write_blocking(enumeration_data)
pio_spi.write_blocking(s23_25)
pio_spi.write_blocking(R29h_SLDET_1) # ShortLED detect for BIST
Bist_odd_2_5V()
print('odd LED pattern')
Bist_even_2_5V()
print('even LED pattern')
# Bist_odd_2_0V()
# print('odd LED pattern')
# Bist_even_2_0V()
# print('even LED pattern')
# バイト列の中で「偶数位のビット」が1になっているビットの総数を数える
def count_even_bits(byte_list):
count = 0 # カウンタ変数countを0で初期化。ここに合計値を蓄積
for value in byte_list: # リストの中身を1つずつ取り出して処理するループ
masked = value & 0b10101010 # 「偶数位のビット」だけを取り出す。(左から第2,4,6,8位を数える)
count += bin(masked)[2:].count('1') # 整数を2進数の文字列に変えて、1の数を数えて、合計する
return count # 全部の value をチェックしたら、1の合計数(偶数位にある1の合計)をcountに返す
# バイト列の中で「奇数位のビット」が1になっているビットの総数を数える
def count_odd_bits(byte_list):
count = 0 # カウンタ変数countを0で初期化。ここに合計値を蓄積
for value in byte_list: # リストの中身を1つずつ取り出して処理するループ
masked = value & 0b01010101 # 「奇数位のビット」だけを取り出す。(右から第1,3,5,7位を数える)
count += bin(masked)[2:].count('1') # 整数を2進数の文字列に変えて、1の数を数えて、合計する
return count # 全部の value をチェックしたら、1の合計数(奇数位にある1の合計)をcountに返す
print(count)
def split_rd_data(raw_data):
# 各32ビットのデータを読み出し、4つの8ビットに分解し、1次元配列として展開します。
rd_data = [] # 空のリストを用意して、デコードしたデータをここに格納します。
for data in raw_data: # Bist_RD_data の各データ(1つずつ)に対して処理します。
rd_data.extend([
(data >> (8 * 3)) & (255), # data を24ビット右シフト、最上位の8ビットを取り出す
(data >> (8 * 2)) & (255), # data を16ビット右シフトして、第2バイトを取り出す
(data >> (8 * 1)) & (255), # data を8ビット右シフトして、第1バイトを取り出す
(data >> (8 * 0)) & (255) # シフトなしで、そのまま最下位バイトを取り出す
])
return rd_data # 最終処理後の1次元配列を返します。その配列には、すべての8ビット値が格納されています。
def process_bist_data(raw_data, count_func):
split_data = split_rd_data(raw_data) # 上の関数でデコードする
sliced_data = split_data[25:] # skip the 25 useless datas in the front
return count_func(sliced_data) #点灯LEDの数を数える関数に渡す
EXPECTED_ODD_BIT_COUNT = 418
EXPECTED_EVEN_BIT_COUNT = 399
# Start up the BIST-Test(even_bit)
def Bist_even_2_5V():
#pio_spi.write_blocking(res_data) # Send reset_data
#utime.sleep_ms(10)
#pio_spi.write_blocking(enumeration_data)
#pio_spi.write_blocking(s23_25)
pio_spi.write_blocking(R29h_SLDET_1) # ShortLED detect for BIST
pio_spi.write_blocking(BIST_ON_even) # 偶数番号のLEDにBIST信号を送って点灯させます。
utime.sleep_ms(2500) # LED点灯(10uA)確認→wait 500ms
Bist_even_RD_data = pio_spi.write_read_blocking(BIST_RD) # BIST Readコマンドを送信し、同時にLEDからの読み出しデータを受信します。
#print(Bist_even_RD_data)
even_bit_count_2_5V = process_bist_data(Bist_even_RD_data, count_even_bits) # count_even_bits 関数を使用して、返されるデータ Bist_even_RD_data を処理し、「偶数位置のLEDが点灯している数」をカウントします。
print(even_bit_count_2_5V)
if even_bit_count_2_5V > 0:
print("LED board NG")
sys.exit("LED灯板不合格") # プログラムを終了
else:
print("LED board OK")
#utime.sleep_ms(10)
#for _ in range(50): # 必要な回数だけ繰り返す
# Bist_even_RD_data = pio_spi.write_read_blocking(BIST_RD)
# even_bit_count = process_bist_data(Bist_even_RD_data, count_even_bits) # count_even_bits 関数を使用して、返されるデータ Bist_even_RD_data を処理し、「偶数位置のLEDが点灯している数」をカウントします。
# print(even_bit_count)
# utime.sleep_ms(10)
#print(f"[VF Check] Even pattern - total LEDs lit: {even_bit_count}")
# if even_bit_count < EXPECTED_EVEN_BIT_COUNT:
# print("NG: One or more LEDs did NOT light up in even pattern!")
# raise SystemExit("BIST_even failure: Stop due to VF too high or disconnection.")
# else:
# print("OK: All expected LEDs lit in BIST_even")
def Bist_odd_2_5V():
#pio_spi.write_blocking(res_data) # Send reset_data
#utime.sleep_ms(10)
#pio_spi.write_blocking(enumeration_data)
#pio_spi.write_blocking(s23_25)
pio_spi.write_blocking(R29h_SLDET_1) # ShortLED detect for BIST
pio_spi.write_blocking(BIST_ON_odd) # SPI通信でコマンドをブロッキング送信、奇数番号のLEDにBIST信号を送って点灯させます。
utime.sleep_ms(2500) # LED点灯(10uA)確認→wait 500ms
Bist_odd_RD_data = pio_spi.write_read_blocking(BIST_RD) # BIST Readコマンドを送信し、同時にLEDからの読み出しデータを受信します。
#print(Bist_odd_RD_data)
odd_bit_count_2_5V = process_bist_data(Bist_odd_RD_data, count_odd_bits) # count_odd_bits 関数を使用して、返されるデータ Bist_odd_RD_data を処理し、「奇数位置のLEDが点灯している数」をカウントします。
print(odd_bit_count_2_5V)
if odd_bit_count_2_5V > 0:
print("LED board NG")
sys.exit("LED灯板不合格") # プログラムを終了
else:
print("LED board OK")
#utime.sleep_ms(10)
#for _ in range(50): # 必要な回数だけ繰り返す
# Bist_odd_RD_data = pio_spi.write_read_blocking(BIST_RD)
# odd_bit_count = process_bist_data(Bist_odd_RD_data, count_odd_bits) # count_odd_bits 関数を使用して、返されるデータ Bist_odd_RD_data を処理し、「奇数位置のLEDが点灯している数」をカウントします。
# print(odd_bit_count)
# utime.sleep_ms(10)
# print(f"[VF Check] Odd pattern - total LEDs lit: {odd_bit_count}")
# if odd_bit_count < EXPECTED_ODD_BIT_COUNT:
# print("NG: One or more LEDs did NOT light up in odd pattern!")
# raise SystemExit("BIST_odd failure: Stop due to VF too high or disconnection.")
# else:
# print("OK: All expected LEDs lit in BIST_odd")
def Bist_even_2_0V():
#pio_spi.write_blocking(res_data) # Send reset_data
#utime.sleep_ms(10)
#pio_spi.write_blocking(enumeration_data)
#pio_spi.write_blocking(s23_25)
pio_spi.write_blocking(R29h_SLDET_2) # ShortLED detect for BIST
pio_spi.write_blocking(BIST_ON_even) # 偶数番号のLEDにBIST信号を送って点灯させます。
utime.sleep_ms(2500) # LED点灯(10uA)確認→wait 500ms
Bist_even_RD_data = pio_spi.write_read_blocking(BIST_RD) # BIST Readコマンドを送信し、同時にLEDからの読み出しデータを受信します。
#print(Bist_even_RD_data)
even_bit_count_2_0V = process_bist_data(Bist_even_RD_data, count_even_bits) # count_even_bits 関数を使用して、返されるデータ Bist_even_RD_data を処理し、「偶数位置のLEDが点灯している数」をカウントします。
print(even_bit_count_2_0V)
if even_bit_count_2_0V < 399:
print("LED board NG")
sys.exit("LED灯板不合格") # プログラムを終了
else:
print("LED board OK")
def Bist_odd_2_0V():
#pio_spi.write_blocking(res_data) # Send reset_data
#utime.sleep_ms(10)
#pio_spi.write_blocking(enumeration_data)
#pio_spi.write_blocking(s23_25)
pio_spi.write_blocking(R29h_SLDET_2) # ShortLED detect for BIST
pio_spi.write_blocking(BIST_ON_odd) # SPI通信でコマンドをブロッキング送信、奇数番号のLEDにBIST信号を送って点灯させます。
utime.sleep_ms(2500) # LED点灯(10uA)確認→wait 500ms
Bist_odd_RD_data = pio_spi.write_read_blocking(BIST_RD) # BIST Readコマンドを送信し、同時にLEDからの読み出しデータを受信します。
#print(Bist_odd_RD_data)
odd_bit_count_2_0V = process_bist_data(Bist_odd_RD_data, count_odd_bits) # count_odd_bits 関数を使用して、返されるデータ Bist_odd_RD_data を処理し、「奇数位置のLEDが点灯している数」をカウントします。
print(odd_bit_count_2_0V)
if odd_bit_count_2_0V < 418:
print("LED board NG")
sys.exit("LED灯板不合格") # プログラムを終了
else:
print("LED board OK")
def change_pwm_all_leds(duty):
for ic in range(0x01, 0x17): # It generates from IC No.1(0x01) to IC No.22(0x16) (that is, decimal 1 to 22).
write_blocking_pwm([ic, 0x26, 0x40], duty) # It is the register address format for setting PWM.
def turn_on_backlight():
led_pin.value(1)
Vddio.value(1)
utime.sleep_ms(10)
cs_pin.value(1)
utime.sleep_ms(1)
pwm.duty_u16(int(65535 * 0.01)) # Send PWM signal, set duty cycle to 1%
utime.sleep_ms(20)
Vled.value(1)
utime.sleep_ms(1)
# Before sending combined_data_2, ensure CS remains high
print("call_write_read_blocking_reset")
pio_spi.write_blocking(res_data) # Send reset_data
utime.sleep_ms(10)
print("call_write_blocking_enu")
pio_spi.write_blocking(enumeration_data)
print("call_write_read")
devID = pio_spi.write_read_blocking(dev_id_data)
print(devID)
print("call_write_s23-25")
pio_spi.write_read_blocking(s23_25)
print("call_write_s17")
pio_spi.write_read_blocking(s17)
print("call_write_s14")
pio_spi.write_read_blocking(s14)
print("call_write_s16")
pio_spi.write_read_blocking(s16)
print("call_write_ILEDn")
pio_spi.write_read_blocking(ILEDn)
# pio_spi.write_blocking(GBL_PWM0) # Broadast(Write with Same data) 1 address from 0x74(GBL_PWM_LOW16_VWDPORT)
print("call_write_e1")
pio_spi.write_read_blocking(e1)
def change_pwm():
write_blocking_pwm([0x01, 0x26, 0x40], duty_value)
write_blocking_pwm([0x02, 0x26, 0x40], duty_value)
write_blocking_pwm([0x03, 0x26, 0x40], duty_value)
write_blocking_pwm([0x04, 0x26, 0x40], duty_value)
write_blocking_pwm([0x04, 0x26, 0x40], duty_value)
write_blocking_pwm([0x04, 0x26, 0x40], duty_value)
write_blocking_pwm([0x04, 0x26, 0x40], duty_value)
write_blocking_pwm([0x05, 0x26, 0x40], duty_value)
write_blocking_pwm([0x06, 0x26, 0x40], duty_value)
write_blocking_pwm([0x07, 0x26, 0x40], duty_value)
write_blocking_pwm([0x08, 0x26, 0x40], duty_value)
write_blocking_pwm([0x09, 0x26, 0x40], duty_value)
write_blocking_pwm([0x0A, 0x26, 0x40], duty_value)
write_blocking_pwm([0x0B, 0x26, 0x40], duty_value)
write_blocking_pwm([0x0C, 0x26, 0x40], duty_value)
write_blocking_pwm([0x0D, 0x26, 0x40], duty_value)
write_blocking_pwm([0x0E, 0x26, 0x40], duty_value)
write_blocking_pwm([0x0F, 0x26, 0x40], duty_value)
write_blocking_pwm([0x10, 0x26, 0x40], duty_value)
write_blocking_pwm([0x11, 0x26, 0x40], duty_value)
write_blocking_pwm([0x12, 0x26, 0x40], duty_value)
write_blocking_pwm([0x13, 0x26, 0x40], duty_value)
write_blocking_pwm([0x14, 0x26, 0x40], duty_value)
write_blocking_pwm([0x15, 0x26, 0x40], duty_value)
write_blocking_pwm([0x16, 0x26, 0x40], duty_value)
def turn_off_backlight():
pio_spi.write_read_blocking(e0)
utime.sleep_ms(100)
Vled.value(0)
pwm.duty_u16(0) # Stop PWM signal
utime.sleep_ms(t2_ms) #1ms
#cs_low() # Set CS low
cs_pin.value(0)
utime.sleep_ms(t3_ms) #50ms # the time from VLED low to VDD low (50ms)
# Set Vddio low
Vddio.value(0)
# Initialize PWM
#pwm = PWM(Pin(9), freq=vsy_freq, duty_u16=0)
sw1_st = 0
status = 0
status_pin.value(status & 1)
key1_press_count = 0 # Reset counter after KEY2 released
while True:
if falling_edge_flag:
print("スイッチが押されました!")
if KEY2.value() == 0:
led_pin.value(1)
judge_LED_board()
Bist_testing()
init_AOI_full_lighting()
while KEY2.value() == 0:
utime.sleep_ms(10)
if KEY1.value() == 0:
while KEY1.value() == 0:
utime.sleep_ms(1)
key1_press_count += 1
if key1_press_count == 1:
pwm = PWM(Pin(9), freq=vsy_freq, duty_u16=0)
pwm.duty_u16(int(65535 * 0.01))
utime.sleep_ms(20)
pio_spi.write_blocking(e1)
change_pwm_all_leds(duty_value_1)
print('Mode 1: all LED on with duty_value_1')
status = 1 # 状態を status = 1 にする
elif key1_press_count == 2:
pio_spi.write_blocking(e1)
change_pwm_all_leds(duty_value_2)
print('Mode 2: all LED on with duty_value_2')
status = 2 # 状態を status = 2 にする
if rising_edge_flag:
print("スイッチが離されました!")
if KEY2.value() == 1:
pwm = PWM(Pin(9), freq=vsy_freq, duty_u16=0)
turn_off_backlight()
led_pin.value(0)
print('all LEDs off')
key1_press_count = 0
# break # exit 【while KEY2 】 loop
# while KEY2.value() == 0: # KEY2がちゃんと戻るのを待つ
# utime.sleep_ms(10)
status = 3 # 状態をstatus = 3 にする
utime.sleep_ms(100)