summaryrefslogtreecommitdiffstats
path: root/tinyusb/tools/build_esp32sx.py
blob: 91953f080c4c1794480de09ad629f9a1e8430d83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import os
import glob
import sys
import subprocess
import time

SUCCEEDED = "\033[32msucceeded\033[0m"
FAILED = "\033[31mfailed\033[0m"
SKIPPED = "\033[33mskipped\033[0m"

success_count = 0
fail_count = 0
skip_count = 0
exit_status = 0

total_time = time.monotonic()

build_format = '| {:23} | {:30} | {:18} | {:7} | {:6} | {:6} |'
build_separator = '-' * 100

def filter_with_input(mylist):
    if len(sys.argv) > 1:
        input_args = list(set(mylist).intersection(sys.argv))
        if len(input_args) > 0:
            mylist[:] = input_args

# Build all examples if not specified
all_examples = []
for entry in os.scandir("examples/device"):
    # Only includes example with CMakeLists.txt for esp32s, and skip board_test to speed up ci
    if entry.is_dir() and os.path.exists(entry.path + "/sdkconfig.defaults") and entry.name != 'board_test':
        all_examples.append(entry.name)
filter_with_input(all_examples)
all_examples.sort()

# Build all boards if not specified
all_boards = []
for entry in os.scandir("hw/bsp/esp32s2/boards"):
    if entry.is_dir():
        all_boards.append(entry.name)
for entry in os.scandir("hw/bsp/esp32s3/boards"):
    if entry.is_dir():
        all_boards.append(entry.name)
filter_with_input(all_boards)
all_boards.sort()

def build_board(example, board):
    global success_count, fail_count, skip_count, exit_status
    start_time = time.monotonic()
    flash_size = "-"
    sram_size = "-"

    # Check if board is skipped
    if skip_example(example, board):
        success = SKIPPED
        skip_count += 1
        print(build_format.format(example, board, success, '-', flash_size, sram_size))
    else:
        subprocess.run("make -C examples/device/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        build_result = subprocess.run("make -j -C examples/device/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

        if build_result.returncode == 0:
            success = SUCCEEDED
            success_count += 1
            (flash_size, sram_size) = build_size(example, board)
        else:
            exit_status = build_result.returncode
            success = FAILED
            fail_count += 1

        build_duration = time.monotonic() - start_time
        print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size))

        if build_result.returncode != 0:
            print(build_result.stdout.decode("utf-8"))

def build_size(example, board):
    #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board)
    elf_file = 'examples/device/{}/_build/{}/*.elf'.format(example, board)
    size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8")
    size_list = size_output.split('\n')[1].split('\t')
    flash_size = int(size_list[0])
    sram_size = int(size_list[1]) + int(size_list[2])
    return (flash_size, sram_size)

def skip_example(example, board):
    return 0

print(build_separator)
print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM'))
print(build_separator)

for example in all_examples:
    for board in all_boards:
        build_board(example, board)

total_time = time.monotonic() - total_time
print(build_separator)
print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time))
print(build_separator)

sys.exit(exit_status)
pan>0; i < MATRIX_ROWS; i++) { matrix[i] = 0; } #ifdef DEBUG_MATRIX_SCAN_RATE matrix_timer = timer_read32(); matrix_scan_count = 0; #endif } // Returns a matrix_row_t whose bits are set if the corresponding key should be // eligible to change in this scan. matrix_row_t debounce_mask(uint8_t row) { matrix_row_t result = 0; for (uint8_t j=0; j < MATRIX_COLS; ++j) { if (debounce_matrix[row * MATRIX_COLS + j]) { --debounce_matrix[row * MATRIX_COLS + j]; } else { result |= (1 << j); } } return result; } // Report changed keys in the given row. Resets the debounce countdowns // corresponding to each set bit in 'change' to DEBOUNCE. void debounce_report(matrix_row_t change, uint8_t row) { for (uint8_t i = 0; i < MATRIX_COLS; ++i) { if (change & (1 << i)) { debounce_matrix[row * MATRIX_COLS + i] = DEBOUNCE; } } } uint8_t matrix_scan(void) { if (mcp23018_status) { // if there was an error if (++mcp23018_reset_loop == 0) { // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans // this will be approx bit more frequent than once per second print("trying to reset mcp23018\n"); mcp23018_status = init_mcp23018(); if (mcp23018_status) { print("left side not responding\n"); } else { print("left side attached\n"); ergodox_blink_all_leds(); } } } #ifdef DEBUG_MATRIX_SCAN_RATE matrix_scan_count++; uint32_t timer_now = timer_read32(); if (TIMER_DIFF_32(timer_now, matrix_timer)>1000) { print("matrix scan frequency: "); pdec(matrix_scan_count); print("\n"); matrix_timer = timer_now; matrix_scan_count = 0; } #endif #ifdef LEFT_LEDS mcp23018_status = ergodox_left_leds_update(); #endif // LEFT_LEDS for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { select_row(i); // and select on left hand select_row(i + MATRIX_ROWS_PER_SIDE); // we don't need a 30us delay anymore, because selecting a // left-hand row requires more than 30us for i2c. matrix_row_t mask = debounce_mask(i); matrix_row_t cols = (read_cols(i) & mask) | (matrix[i] & ~mask); debounce_report(cols ^ matrix[i], i); matrix[i] = cols; // grab cols from right hand mask = debounce_mask(i + MATRIX_ROWS_PER_SIDE); cols = (read_cols(i + MATRIX_ROWS_PER_SIDE) & mask) | (matrix[i + MATRIX_ROWS_PER_SIDE] & ~mask); debounce_report(cols ^ matrix[i + MATRIX_ROWS_PER_SIDE], i + MATRIX_ROWS_PER_SIDE); matrix[i + MATRIX_ROWS_PER_SIDE] = cols; unselect_rows(); } matrix_scan_quantum(); return 1; } bool matrix_is_modified(void) // deprecated and evidently not called. { return true; } inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1<<col)); } inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } void matrix_print(void) { print("\nr/c 0123456789ABCDEF\n"); for (uint8_t row = 0; row < MATRIX_ROWS; row++) { phex(row); print(": "); pbin_reverse16(matrix_get_row(row)); print("\n"); } } uint8_t matrix_key_count(void) { uint8_t count = 0; for (uint8_t i = 0; i < MATRIX_ROWS; i++) { count += bitpop16(matrix[i]); } return count; } /* Column pin configuration * * Teensy * col: 0 1 2 3 4 5 * pin: F0 F1 F4 F5 F6 F7 * * MCP23018 * col: 0 1 2 3 4 5 * pin: B5 B4 B3 B2 B1 B0 */ static void init_cols(void) { // init on mcp23018 // not needed, already done as part of init_mcp23018() // init on teensy // Input with pull-up(DDR:0, PORT:1) DDRF &= ~(1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<1 | 1<<0); PORTF |= (1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<1 | 1<<0); } static matrix_row_t read_cols(uint8_t row) { if (row < 7) { if (mcp23018_status) { // if there was an error return 0; } else { uint8_t data = 0; mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out; mcp23018_status = i2c_write(GPIOB); if (mcp23018_status) goto out; mcp23018_status = i2c_start(I2C_ADDR_READ); if (mcp23018_status) goto out; data = i2c_readNak(); data = ~data; out: i2c_stop(); return data; } } else { /* read from teensy * bitmask is 0b11110011, but we want those all * in the lower six bits. * we'll return 1s for the top two, but that's harmless. */ return ~((PINF & 0x03) | ((PINF & 0xF0) >> 2)); } } /* Row pin configuration * * Teensy * row: 7 8 9 10 11 12 13 * pin: B0 B1 B2 B3 D2 D3 C6 * * MCP23018 * row: 0 1 2 3 4 5 6 * pin: A0 A1 A2 A3 A4 A5 A6 */ static void unselect_rows(void) { // no need to unselect on mcp23018, because the select step sets all // the other row bits high, and it's not changing to a different // direction // unselect on teensy // Hi-Z(DDR:0, PORT:0) to unselect DDRB &= ~(1<<0 | 1<<1 | 1<<2 | 1<<3); PORTB &= ~(1<<0 | 1<<1 | 1<<2 | 1<<3); DDRD &= ~(1<<2 | 1<<3); PORTD &= ~(1<<2 | 1<<3); DDRC &= ~(1<<6); PORTC &= ~(1<<6); } static void select_row(uint8_t row) { if (row < 7) { // select on mcp23018 if (mcp23018_status) { // if there was an error // do nothing } else { // set active row low : 0 // set other rows hi-Z : 1 mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out; mcp23018_status = i2c_write(GPIOA); if (mcp23018_status) goto out; mcp23018_status = i2c_write(0xFF & ~(1<<row)); if (mcp23018_status) goto out; out: i2c_stop(); } } else { // select on teensy // Output low(DDR:1, PORT:0) to select switch (row) { case 7: DDRB |= (1<<0); PORTB &= ~(1<<0); break; case 8: DDRB |= (1<<1); PORTB &= ~(1<<1); break; case 9: DDRB |= (1<<2); PORTB &= ~(1<<2); break; case 10: DDRB |= (1<<3); PORTB &= ~(1<<3); break; case 11: DDRD |= (1<<2); PORTD &= ~(1<<3); break; case 12: DDRD |= (1<<3); PORTD &= ~(1<<3); break; case 13: DDRC |= (1<<6); PORTC &= ~(1<<6); break; } } }