Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syntax run rework to reduce overhead #144

Merged
merged 8 commits into from
Nov 22, 2024
29 changes: 21 additions & 8 deletions src/bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ struct _bytecode {

const char* error_message;
const char* data_message;
// The following fields appear to be overloaded by the individual protocols. Thus,
// they have NO DEFINED MEANING outside of the protocol-specific convention, which
// is allowed to vary between protocols.
//
// As one example, HWLED protocol uses only the `out_data` field, and even then,
// the value stored depends on the protocol:
// * WS2812: 24 least significant bits: RGB value (top 8 bits are forced to be zero before used).
// * APA102: 24 least significant bits: RGB value (top 8 bits are currently forced to 0xFF for full-brightness).
uint32_t bits; // 0-32 bits?
uint32_t repeat; // 0-0xffff repeat
uint32_t out_data; // 32 data bits
uint32_t in_data; // up to 32bits results? BUT: how to deal with repeated reads????
uint32_t out_data; // 32 data bits (to be sent over wire(s))
uint32_t in_data; // 32 data bits (read from the wire(s))
};
static_assert(
sizeof(struct _bytecode) <= 28,
Expand All @@ -43,12 +51,17 @@ struct _bytecode_result {
const char* message;
};

enum SYNTAX_RESULT {
SRES_NONE = 0,
SRES_DEBUG,
SRES_INFO,
SRES_WARN,
SRES_ERROR
typedef enum {
SSTATUS_OK,
SSTATUS_ERROR
} SYNTAX_STATUS;

enum SYNTAX_ERRORS {
SERR_NONE = 0,
SERR_DEBUG,
SERR_INFO,
SERR_WARN,
SERR_ERROR
};

enum SYNTAX {
Expand Down
2 changes: 1 addition & 1 deletion src/mode/binloopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void binloopback_read(struct _bytecode* result, struct _bytecode* next) {
while (!bin_tx_fifo_try_get(&c)) {
timeout--;
if (!timeout) {
result->error = SRES_ERROR;
result->error = SERR_ERROR;
result->error_message = GET_T(T_UART_NO_DATA_READ);
return;
}
Expand Down
12 changes: 6 additions & 6 deletions src/mode/dummy1.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ void dummy1_write(struct _bytecode* result, struct _bytecode* next) {
if (result->out_data == 0xff) {
/*
Error result codes.
SRES_NONE
SRES_DEBUG Displays error_message, does not halt execution
SRES_INFO Displays error_message, does not halt execution
SRES_WARN Displays error_message, does not halt execution
SRES_ERROR Displays error_message, halts execution
SERR_NONE
SERR_DEBUG Displays error_message, does not halt execution
SERR_INFO Displays error_message, does not halt execution
SERR_WARN Displays error_message, does not halt execution
SERR_ERROR Displays error_message, halts execution
*/
result->error = SRES_ERROR; // mode error halts execution
result->error = SERR_ERROR; // mode error halts execution
result->error_message = err;
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/mode/hw1wire.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void hw1wire_start(struct _bytecode* result, struct _bytecode* next) {

if (bio_get(M_OW_OWD) == 0) {
result->error_message = GET_T(T_HWI2C_NO_PULLUP_DETECTED);
result->error = SRES_WARN;
result->error = SERR_WARN;
}
#ifdef BP_OLD_HW1WIRE
uint8_t device_detect = onewire_reset();
Expand All @@ -74,7 +74,7 @@ void hw1wire_start(struct _bytecode* result, struct _bytecode* next) {
// result->error_message = GET_T(T_HW1WIRE_PRESENCE_DETECT);
} else {
result->error_message = GET_T(T_HW1WIRE_NO_DEVICE);
result->error = SRES_ERROR;
result->error = SERR_ERROR;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/mode/hw2wire.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void hw2wire_start(struct _bytecode* result, struct _bytecode* next) {
result->data_message = GET_T(T_HWI2C_START);
if (checkshort()) {
result->error_message = GET_T(T_HWI2C_NO_PULLUP_DETECTED);
result->error = SRES_WARN;
result->error = SERR_WARN;
}
pio_hw2wire_start();
}
Expand Down
2 changes: 1 addition & 1 deletion src/mode/hwhduart.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ void hwhduart_read(struct _bytecode* result, struct _bytecode* next) {
while (!hwuart_pio_read(&raw, &cooked)) {
timeout--;
if (!timeout) {
result->error = SRES_ERROR;
result->error = SERR_ERROR;
result->error_message = GET_T(T_UART_NO_DATA_READ);
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/mode/hwi2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ bool hwi2c_error(hwi2c_status_t error, struct _bytecode* result) {
switch (error) {
case HWI2C_TIMEOUT:
result->error_message = GET_T(T_HWI2C_TIMEOUT);
result->error = SRES_ERROR;
result->error = SERR_ERROR;
pio_i2c_resume_after_error();
return true;
break;
Expand All @@ -154,7 +154,7 @@ bool hwi2c_error(hwi2c_status_t error, struct _bytecode* result) {
void hwi2c_start(struct _bytecode* result, struct _bytecode* next) {
if (hwi2c_checkshort()) {
result->error_message = GET_T(T_HWI2C_NO_PULLUP_DETECTED);
result->error = SRES_WARN;
result->error = SERR_WARN;
}

hwi2c_status_t i2c_status;
Expand Down
81 changes: 60 additions & 21 deletions src/mode/hwled.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static const struct ui_prompt leds_menu[] = {
.menu_action = 0,
.config = &prompt_list_cfg
},
{
/*{
.description = T_HWLED_NUM_LEDS_MENU,
.menu_items = leds_num_menu,
.menu_items_count = count_of(leds_num_menu),
Expand All @@ -78,7 +78,7 @@ static const struct ui_prompt leds_menu[] = {
.defval = 1,
.menu_action = 0,
.config = &prompt_int_cfg
}
}*/
};

uint32_t hwled_setup(void) {
Expand All @@ -89,7 +89,7 @@ uint32_t hwled_setup(void) {
const mode_config_t config_t[] = {
// clang-format off
{ "$.device", &mode_config.device, MODE_CONFIG_FORMAT_DECIMAL },
{ "$.num_leds", &mode_config.num_leds, MODE_CONFIG_FORMAT_DECIMAL },
//{ "$.num_leds", &mode_config.num_leds, MODE_CONFIG_FORMAT_DECIMAL },
// clang-format on
};

Expand All @@ -112,14 +112,14 @@ uint32_t hwled_setup(void) {
return 0;
}
mode_config.device--;
if (mode_config.device == 2) {
/*if (mode_config.device == 2) {
mode_config.num_leds = RGB_LEN;
} else {
ui_prompt_uint32(&result, &leds_menu[1], &mode_config.num_leds);
if (result.exit) {
return 0;
}
}
}*/

storage_save_mode(config_file, config_t, count_of(config_t));

Expand All @@ -133,6 +133,9 @@ uint32_t hwled_setup_exc(void) {
pio_config.sm = 0;
switch (mode_config.device) {
case M_LED_WS2812:
if(!system_bio_claim(true, M_LED_SDO, BP_PIN_MODE, pin_labels[0])){
printf("\r\nError: Unable to claim SDO pin");
}
mode_config.baudrate = 800000;
bio_buf_output(M_LED_SDO);
// success = pio_claim_free_sm_and_add_program_for_gpio_range(&ws2812_program, &pio_config.pio,
Expand All @@ -147,10 +150,14 @@ uint32_t hwled_setup_exc(void) {
pio_config.offset,
bio2bufiopin[M_LED_SDO],
(float)mode_config.baudrate,
false);
system_bio_claim(true, M_LED_SDO, BP_PIN_MODE, pin_labels[0]);
false);
break;
case M_LED_APA102:
if(!(system_bio_claim(true, M_LED_SDO, BP_PIN_MODE, pin_labels[0]) &&
system_bio_claim(true, M_LED_SCL, BP_PIN_MODE, pin_labels[1]))){
printf("\r\nError: Unable to claim SDO or SCL pin");
return 0;
}
mode_config.baudrate = (5 * 1000 * 1000);
bio_buf_output(M_LED_SDO);
bio_buf_output(M_LED_SCL);
Expand All @@ -167,8 +174,7 @@ uint32_t hwled_setup_exc(void) {
mode_config.baudrate,
bio2bufiopin[M_LED_SCL],
bio2bufiopin[M_LED_SDO]);
system_bio_claim(true, M_LED_SDO, BP_PIN_MODE, pin_labels[0]);
system_bio_claim(true, M_LED_SCL, BP_PIN_MODE, pin_labels[1]);

break;
case M_LED_WS2812_ONBOARD: // internal LEDs, stop any in-progress stuff
mode_config.baudrate = 800000;
Expand All @@ -181,14 +187,16 @@ uint32_t hwled_setup_exc(void) {
}
device_cleanup = mode_config.device;
system_config.subprotocol_name = led_device_type[mode_config.device];
system_config.num_bits=32;
return 1;
}

void hwled_start(struct _bytecode* result, struct _bytecode* next) {
switch (mode_config.device) {
case M_LED_WS2812:
case M_LED_WS2812_ONBOARD:
hwled_wait_idle(); //wait until the FIFO is empty and the state machine is idle
busy_wait_us(100); // 50ms delay to reset
busy_wait_us(65); // >50us delay to reset
result->data_message = GET_T(T_HWLED_RESET);
break;
case M_LED_APA102:
Expand All @@ -205,7 +213,7 @@ void hwled_stop(struct _bytecode* result, struct _bytecode* next) {
case M_LED_WS2812:
case M_LED_WS2812_ONBOARD:
hwled_wait_idle(); //wait until the FIFO is empty and the state machine is idle
busy_wait_us(100); // 50ms delay to reset
busy_wait_us(65); // >50us delay to reset
result->data_message = GET_T(T_HWLED_RESET);
break;
case M_LED_APA102:
Expand All @@ -218,14 +226,35 @@ void hwled_stop(struct _bytecode* result, struct _bytecode* next) {
}

void hwled_write(struct _bytecode* result, struct _bytecode* next) {
uint32_t temp;

// Protocol-specific:
// * parameter `next` is unused
// * parameter `result->out_data` contains a 24-bit RGB value to send
// NOTE: for WS2812, the top 8 bits are cleared to zero.
// NOTE: for APA102, the top 8 bits are forced to 0xFF (full brightness).
// UNDOCUMENTED:
// Order in which the bytes are sent is NOT documented here.
// Caller must test to determin the proper RGB value order for their hardware.
switch (mode_config.device) {
// TODO: add support for RGBW (RGB + white)?
// TODO: add support for RGBWW (RGB + cool white + warm white)?
// TODO: add support for RGBWWA (RGB + cool white + warm white + amber)?
case M_LED_WS2812:
// NOTE: Only supporting 24-bit RGB values for now.
// As a hack, callers can likely use RGBW by packing
// three pixels' data into four 24-bit values:
// 0x00R1G1B1 0x00W1R2G2 0x00B2W2R3 0x00G3B3W3
pio_sm_put_blocking(pio_config.pio, pio_config.sm, (result->out_data << 8u));
break;
case M_LED_APA102:
pio_sm_put_blocking(pio_config.pio, pio_config.sm, ((0xff<<24)|result->out_data));
// only set to full brightness if the top bits from caller are zero
// otherwise, allow the caller to set the global brightness bits for
// more advanced brightness setting.
if ((result->out_data & 0xE0000000) == 0) {
result->out_data|=(0xff<<24);
//pio_sm_put_blocking(pio_config.pio, pio_config.sm, ((0xff<<24)|result->out_data));
}//else{
pio_sm_put_blocking(pio_config.pio, pio_config.sm, result->out_data);
//}
break;
case M_LED_WS2812_ONBOARD:
rgb_put(result->out_data);
Expand Down Expand Up @@ -267,7 +296,7 @@ void hwled_cleanup(void) {

void hwled_settings(void) {
ui_prompt_mode_settings_string(GET_T(T_HWLED_DEVICE_MENU), GET_T(leds_type_menu[mode_config.device].description), 0x00);
ui_prompt_mode_settings_int(GET_T(T_HWLED_NUM_LEDS_MENU), mode_config.num_leds, 0x00);
//ui_prompt_mode_settings_int(GET_T(T_HWLED_NUM_LEDS_MENU), mode_config.num_leds, 0x00);
}

void hwled_help(void) {
Expand All @@ -278,15 +307,25 @@ uint32_t hwled_get_speed(void) {
return mode_config.baudrate;
}

void hwled_wait_idle(void){
//wait until the FIFO is empty and the state machine is idle
uint32_t timeout = 100000;

bool hwled_is_idle(void) {
// Correct way to detect the state machine is idle because of an empty FIFO:
// 1. Clear the (latching) state machine stall bit
// 2. Check if the state machine TX fifo is empty
// 3. THEN check if the state machine stall bit is set
uint32_t SM_STALL_MASK = 1u << (PIO_FDEBUG_TXSTALL_LSB + pio_config.sm);
pio_config.pio->fdebug = SM_STALL_MASK; // writing a 1 clears the bit

pio_config.pio->fdebug = SM_STALL_MASK;
// NOTE: the order of these operations *DOES* matter!
bool result =
pio_sm_is_tx_fifo_empty(pio_config.pio, pio_config.sm) &&
(pio_config.pio->fdebug & SM_STALL_MASK);
return result;
}

while (!(pio_config.pio->fdebug & SM_STALL_MASK)) {
// NOTE: Function must have no parameters ... this is a protocol entry point.
void hwled_wait_idle(void) {
uint32_t timeout = 100000;
while (!hwled_is_idle()) {
timeout--;
if (!timeout) {
printf("Timeout, error!");
Expand Down
4 changes: 2 additions & 2 deletions src/mode/hwuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ void hwuart_read(struct _bytecode* result, struct _bytecode* next) {
while (!uart_is_readable(M_UART_PORT)) {
timeout--;
if (!timeout) {
result->error = SRES_ERROR;
result->error = SERR_ERROR;
result->error_message = GET_T(T_UART_NO_DATA_READ);
return;
}
Expand All @@ -304,7 +304,7 @@ void hwuart_read(struct _bytecode* result, struct _bytecode* next) {
if (uart_is_readable(M_UART_PORT)) {
result->in_data = uart_getc(M_UART_PORT);
} else {
result->error = SRES_ERROR;
result->error = SERR_ERROR;
result->error_message = GET_T(T_UART_NO_DATA_READ);
}
bio_put(M_UART_RTS, 1);
Expand Down
Loading
Loading