From: Martin Mares Date: Sun, 14 May 2023 12:40:09 +0000 (+0200) Subject: test-display2: No longer needed X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=e9ed60daa4516476159d894f87ca76e4774d58f1;p=home-hw.git test-display2: No longer needed --- diff --git a/test-display2/Makefile b/test-display2/Makefile deleted file mode 100644 index 8063dfb..0000000 --- a/test-display2/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -ROOT=.. -BINARY=test -OBJS=main.o -LIB_OBJS=util-debug.o - -WITH_BOOT_LOADER=1 -WITH_DFU_FLASH=1 -DFU_ARGS=-d 4242:0007 -# DFU_ARGS=-d 4242:0008 - -include $(ROOT)/mk/bluepill.mk diff --git a/test-display2/README b/test-display2/README deleted file mode 100644 index 19ac2c9..0000000 --- a/test-display2/README +++ /dev/null @@ -1,30 +0,0 @@ -Assignment of peripherals and pins -================================== - -I2C1 display -USART1 debugging - - - Blue Pill pinout - +--------------------+ - | VBATT 3.3V | -BluePill LED | PC13 GND | display power - | PC14 5V | display power (white side of connector) - | PC15 PB9 | - | PA0 PB8 | - | PA1 PB7 | SDA1 display (white side of connector) - | PA2 PB6 | SCL1 display - | PA3 PB5 | - | PA4 PB4 | - | PA5 PB3 | - | PA6 PA15 | - | PA7 PA12 | - | PB0 PA11 | - | PB1 PA10 | RXD1 - debugging console - | PB10 PA9 | TXD1 - debugging console - | PB11 PA8 | SFH5110 output (white side of connector) - | RESET PB15 | - | 3.3 V PB14 | - | GND PB13 | - | GND PB12 | - +--------------------+ diff --git a/test-display2/config.h b/test-display2/config.h deleted file mode 100644 index 50926f9..0000000 --- a/test-display2/config.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Workshop Clock -- Configuration - * - * (c) 2020-2023 Martin Mareš - */ - -// Processor clock - -#define CPU_CLOCK_MHZ 72 - -// Debugging port - -#define DEBUG_USART USART1 -#define DEBUG_LED_BLUEPILL - -// Testing of IR receiver - -#undef IR_TEST diff --git a/test-display2/host/Makefile b/test-display2/host/Makefile deleted file mode 100644 index 5e6e00c..0000000 --- a/test-display2/host/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -UCWCF:=$(shell PKG_CONFIG_PATH=$(LIBUCW)/lib/pkgconfig pkg-config --cflags libucw) -UCWLF:=$(shell PKG_CONFIG_PATH=$(LIBUCW)/lib/pkgconfig pkg-config --libs libucw) - -CFLAGS=-std=gnu99 -O2 -Wall -Wextra -Wno-parentheses $(UCWCF) -LDLIBS=-lusb-1.0 $(UCWLF) - -all: test - -test: test.c - -clean: - rm -f test diff --git a/test-display2/host/test.c b/test-display2/host/test.c deleted file mode 100644 index cad8474..0000000 --- a/test-display2/host/test.c +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include - -struct libusb_context *usb_ctxt; -struct libusb_device_handle *devh; - -static libusb_device *find_device(void) -{ - libusb_device **devlist; - ssize_t devn = libusb_get_device_list(usb_ctxt, &devlist); - if (devn < 0) - { - fprintf(stderr, "Cannot enumerate USB devices: error %d\n", (int) devn); - exit(1); - } - - for (ssize_t i=0; itm_hour / 10, - tm->tm_hour % 10, - tm->tm_min / 10, - tm->tm_min % 10, - (tm->tm_sec % 2 ? 0xff : 0), - }; - int transferred; - if (err = libusb_bulk_transfer(devh, 0x01, req, 5, &transferred, 1000)) - die("Transfer failed: error %d", err); - // printf("Transferred %d bytes\n", transferred); - -#if 0 - unsigned char resp[64]; - int received; - if (err = libusb_bulk_transfer(devh, 0x82, resp, 64, &received, 2000)) - die("Receive failed: error %d", err); - // printf("Received %d bytes\n", received); - if (received >= 12) - { - int t = get_u32_be(resp); - int p = get_u32_be(resp + 4); - uint cnt = get_u32_be(resp + 8); - msg(L_INFO, "Temperature %d ddegC, pressure %d Pa, cnt %u", t, p, cnt); - } -#endif - - sleep(1); - } - - return 0; -} diff --git a/test-display2/main.c b/test-display2/main.c deleted file mode 100644 index 50ce567..0000000 --- a/test-display2/main.c +++ /dev/null @@ -1,633 +0,0 @@ -/* - * Workshop Clock - * - * (c) 2020-2023 Martin Mareš - */ - -#include "util.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static void ep82_send(u32 key_code); - -/*** Hardware init ***/ - -static void clock_init(void) -{ - rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); - - rcc_periph_clock_enable(RCC_GPIOA); - rcc_periph_clock_enable(RCC_GPIOB); - rcc_periph_clock_enable(RCC_GPIOC); - rcc_periph_clock_enable(RCC_I2C1); - rcc_periph_clock_enable(RCC_USART1); - rcc_periph_clock_enable(RCC_USB); - rcc_periph_clock_enable(RCC_TIM1); - - rcc_periph_reset_pulse(RST_GPIOA); - rcc_periph_reset_pulse(RST_GPIOB); - rcc_periph_reset_pulse(RST_GPIOC); - rcc_periph_reset_pulse(RST_I2C1); - rcc_periph_reset_pulse(RST_USART1); - rcc_periph_reset_pulse(RST_USB); - rcc_periph_reset_pulse(RST_TIM1); -} - -static void gpio_init(void) -{ - // PA9 = TXD1 for debugging console - // PA10 = RXD1 for debugging console - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9); - gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO10); - - // PC13 = BluePill LED - gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); - gpio_clear(GPIOC, GPIO13); - - // PB7 = SDA for display controller - // PB6 = SCL for display controller - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO6 | GPIO7); - - // PA8 = SFH5110 output (5V tolerant) connected to TIM1_CH1 - gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO8); -} - -static void usart_init(void) -{ - usart_set_baudrate(USART1, 115200); - usart_set_databits(USART1, 8); - usart_set_stopbits(USART1, USART_STOPBITS_1); - usart_set_mode(USART1, USART_MODE_TX); - usart_set_parity(USART1, USART_PARITY_NONE); - usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE); - - usart_enable(USART1); -} - -/*** System ticks ***/ - -static volatile u32 ms_ticks; - -void sys_tick_handler(void) -{ - ms_ticks++; -} - -static void tick_init(void) -{ - systick_set_frequency(1000, CPU_CLOCK_MHZ * 1000000); - systick_counter_enable(); - systick_interrupt_enable(); -} - -static void delay_ms(uint ms) -{ - u32 start_ticks = ms_ticks; - while (ms_ticks - start_ticks < ms) - ; -} - -/*** Display ***/ - -/* - * Display digits: - * - * ---- 40 ---- - * | | - * | | - * 20 80 - * | | - * | | - * ---- 10 ---- - * | | - * | | - * 08 02 - * | | - * | | - * ---- 04 ---- - * (01) - */ - -static byte disp[4]; -static byte ctrl = 0x56; - -static const byte disp_font[] = { - [0] = 0xee, - [1] = 0x82, - [2] = 0xdc, - [3] = 0xd6, - [4] = 0xb2, - [5] = 0x76, - [6] = 0x7e, - [7] = 0xc2, - [8] = 0xfe, - [9] = 0xf6, - [10] = 0xea, - [11] = 0x3e, - [12] = 0x6c, - [13] = 0x9e, - [14] = 0x7c, - [15] = 0x78, -}; - -static void display_update(void) -{ - // debug_puts("Display update\n"); - - byte cmds[4]; - cmds[0] = 0; - cmds[1] = ctrl; - cmds[2] = ((disp[1] & 0x88) >> 3) | ((disp[1] & 0x44) >> 1) | ((disp[1] & 0x22) << 1) | ((disp[1] & 0x11) << 3); - cmds[3] = disp[0]; - i2c_transfer7(I2C1, 0x76/2, (byte *) cmds, sizeof(cmds), NULL, 0); - - cmds[2] = ((disp[3] & 0x88) >> 3) | ((disp[3] & 0x44) >> 1) | ((disp[3] & 0x22) << 1) | ((disp[3] & 0x11) << 3); - cmds[3] = disp[2]; - i2c_transfer7(I2C1, 0x70/2, (byte *) cmds, sizeof(cmds), NULL, 0); - - // debug_puts("Update done\n"); -} - -static void display_init(void) -{ - debug_puts("I2C init\n"); - i2c_peripheral_disable(I2C1); - i2c_set_speed(I2C1, i2c_speed_sm_100k, rcc_apb1_frequency / 1000000); - i2c_peripheral_enable(I2C1); - - disp[0] = 0x10; - disp[1] = 0x10; - disp[2] = 0x10; - disp[3] = 0x10; - display_update(); -} - -/*** Infrared Remote Control ***/ - -static void ir_init(void) -{ - debug_puts("IR init\n"); - - // TIM1 will measure pulses and spaces between them with 1μs resolution - timer_set_prescaler(TIM1, 71); // 72 MHz / 72 = 1 MHz - timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); - timer_set_period(TIM1, 65535); - timer_update_on_overflow(TIM1); - - // IC1 will trigger on TI1 (TIM1_CH1) falling edge - timer_ic_set_input(TIM1, TIM_IC1, TIM_IC_IN_TI1); - // timer_ic_set_filter(TIM1, TIM_IC1, TIM_IC_OFF); - timer_set_oc_polarity_low(TIM1, TIM_OC1); // OC functions affect IC, too - - // IC2 will trigger on TI1 (TIM1_CH1) rising edge - timer_ic_set_input(TIM1, TIM_IC2, TIM_IC_IN_TI1); - timer_set_oc_polarity_high(TIM1, TIM_OC2); - - // OC3 will trigger on a break longer than 50 ms - timer_set_oc_mode(TIM1, TIM_OC3, TIM_OCM_ACTIVE); - timer_set_oc_value(TIM1, TIM_OC3, 30000); - - // Program slave controller to reset the timer on IC1 - timer_slave_set_trigger(TIM1, TIM_SMCR_TS_TI1FP1); - timer_slave_set_mode(TIM1, TIM_SMCR_SMS_RM); - - // Request interrupts - timer_enable_irq(TIM1, TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC3IE); - nvic_enable_irq(NVIC_TIM1_CC_IRQ); - - // Enable ICs and OCs - timer_enable_oc_output(TIM1, TIM_OC1); - timer_enable_oc_output(TIM1, TIM_OC2); - timer_enable_oc_output(TIM1, TIM_OC3); - - timer_enable_counter(TIM1); -} - -// Circular queue of pulse durations -#define IR_MAX_PULSES 32 -static u32 ir_pulses[IR_MAX_PULSES]; // Top 16 bits = mark, bottom 16 bits = space -static u16 ir_last_pulse; -static uint ir_pulses_rx, ir_pulses_tx; - -#define IR_INF 0xffff - -#define IR_MARK(x) (uint)((x) >> 16) -#define IR_SPACE(x) (uint)((x) & 0xffff) - -static inline bool between(uint x, uint min, uint max) -{ - return x >= min && x <= max; -} - -static void ir_record_pulse(uint mark, uint space) -{ - uint i = ir_pulses_tx; - ir_pulses_tx = (i + 1) % IR_MAX_PULSES; - if (ir_pulses_tx != ir_pulses_rx) { - ir_pulses[i] = (mark << 16) | space; - } else { - // Overflow detected - ir_pulses[i] = (IR_INF << 16) | IR_INF; - } -} - -void tim1_cc_isr(void) -{ - if (TIM_SR(TIM1) & TIM_SR_CC1IF) { - TIM_SR(TIM1) &= ~TIM_SR_CC1IF; - u16 now = TIM_CCR1(TIM1); - if (ir_last_pulse) { - ir_record_pulse(ir_last_pulse, now - ir_last_pulse); - ir_last_pulse = 0; - } - } - if (TIM_SR(TIM1) & TIM_SR_CC2IF) { - TIM_SR(TIM1) &= ~TIM_SR_CC2IF; - ir_last_pulse = TIM_CCR2(TIM1); - } - if (TIM_SR(TIM1) & TIM_SR_CC3IF) { - TIM_SR(TIM1) &= ~TIM_SR_CC3IF; - if (ir_last_pulse) { - ir_record_pulse(ir_last_pulse, IR_INF); - ir_last_pulse = 0; - } - } -} - -static u32 ir_get_pulse(void) -{ - u32 out = 0; - - cm_disable_interrupts(); - if (ir_pulses_rx != ir_pulses_tx) { - out = ir_pulses[ir_pulses_rx]; - ir_pulses_rx = (ir_pulses_rx + 1) % IR_MAX_PULSES; - } - cm_enable_interrupts(); - return out; -} - -// Decoder for Onkyo RC-748S - -static u32 ir_blink_start; - -static void ir_decode(void) -{ - u32 pulse = ir_get_pulse(); - if (!pulse) - return; - - uint mark = IR_MARK(pulse); - uint space = IR_SPACE(pulse); - -#ifdef IR_TEST - debug_printf("IR: %d %d\n", mark, space); - return; -#endif - - static u16 ir_bits; - static u32 ir_code; -#define IR_ERR 0xff - - // debug_printf("IR(%d): %d %d\n", ir_bits, mark, space); - - if (space == IR_INF) { - ir_bits = 0; - } else if (ir_bits == IR_ERR) { - // Error state - } else if (ir_bits == 0) { - // Start? - if (between(mark, 8900, 9200)) { - if (between(space, 4200, 4600)) { - ir_bits = 1; - ir_code = 0; - } else if (between(space, 2000, 2300)) { - debug_printf("IR: => REP\n"); - ir_bits = IR_ERR; - } - } - } else { - if (between(mark, 500, 700)) { - ir_bits++; - if (between(space, 400, 700)) { - // 0 - } else if (between(space, 1500, 1800)) { - // 1 - ir_code |= 1U << (33 - ir_bits); - } else { - ir_bits = IR_ERR; - } - if (ir_bits == 33) { - debug_printf("IR: => %08x\n", (uint)ir_code); - disp[3] |= 0x01; - ir_blink_start = ms_ticks; - display_update(); - ir_bits = IR_ERR; - ep82_send(ir_code); - } - } else { - ir_bits = IR_ERR; - } - } -} - -/*** USB ***/ - -static usbd_device *usbd_dev; - -enum usb_string { - STR_MANUFACTURER = 1, - STR_PRODUCT, - STR_SERIAL, -}; - -static char usb_serial_number[13]; - -static const char *usb_strings[] = { - "United Computer Wizards", - "Workshop Clock", - usb_serial_number, -}; - -static const struct usb_device_descriptor device = { - .bLength = USB_DT_DEVICE_SIZE, - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0200, - .bDeviceClass = 0xFF, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = 64, - .idVendor = 0x4242, - .idProduct = 0x0007, - .bcdDevice = 0x0000, - .iManufacturer = STR_MANUFACTURER, - .iProduct = STR_PRODUCT, - .iSerialNumber = STR_SERIAL, - .bNumConfigurations = 1, -}; - -static const struct usb_endpoint_descriptor endpoints[] = {{ - // Bulk end-point for sending values to the display - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x01, - .bmAttributes = USB_ENDPOINT_ATTR_BULK, - .wMaxPacketSize = 64, - .bInterval = 1, -}, { - // Bulk end-point for receiving remote control keys - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x82, - .bmAttributes = USB_ENDPOINT_ATTR_BULK, - .wMaxPacketSize = 4, - .bInterval = 1, -}}; - -static const struct usb_interface_descriptor iface = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = 0xFF, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .iInterface = 0, - .endpoint = endpoints, -}; - -static const struct usb_dfu_descriptor dfu_function = { - .bLength = sizeof(struct usb_dfu_descriptor), - .bDescriptorType = DFU_FUNCTIONAL, - .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH, - .wDetachTimeout = 255, - .wTransferSize = 1024, - .bcdDFUVersion = 0x0100, -}; - -static const struct usb_interface_descriptor dfu_iface = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 1, - .bAlternateSetting = 0, - .bNumEndpoints = 0, - .bInterfaceClass = 0xFE, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 1, - .iInterface = 0, - - .extra = &dfu_function, - .extralen = sizeof(dfu_function), -}; - -static const struct usb_interface ifaces[] = {{ - .num_altsetting = 1, - .altsetting = &iface, -}, { - .num_altsetting = 1, - .altsetting = &dfu_iface, -}}; - -static const struct usb_config_descriptor config = { - .bLength = USB_DT_CONFIGURATION_SIZE, - .bDescriptorType = USB_DT_CONFIGURATION, - .wTotalLength = 0, - .bNumInterfaces = 2, - .bConfigurationValue = 1, - .iConfiguration = 0, - .bmAttributes = 0x80, - .bMaxPower = 50, // multiplied by 2 mA - .interface = ifaces, -}; - -static bool usb_configured; -static uint8_t usbd_control_buffer[64]; - -static bool usb_tx_in_flight; -static byte ep82_tx_buffer[4]; - -static byte disp_alive; - -static void dfu_detach_complete(usbd_device *dev UNUSED, struct usb_setup_data *req UNUSED) -{ - // Reset to bootloader, which implements the rest of DFU - debug_printf("Switching to DFU\n"); - debug_flush(); - scb_reset_core(); -} - -static enum usbd_request_return_codes dfu_control_cb(usbd_device *dev UNUSED, - struct usb_setup_data *req, - uint8_t **buf UNUSED, - uint16_t *len UNUSED, - void (**complete)(usbd_device *dev, struct usb_setup_data *req)) -{ - if (req->bmRequestType != 0x21 || req->bRequest != DFU_DETACH) - return USBD_REQ_NOTSUPP; - - *complete = dfu_detach_complete; - return USBD_REQ_HANDLED; -} - -static void ep01_cb(usbd_device *dev, uint8_t ep UNUSED) -{ - // We received a frame from the USB host - byte buf[8]; - uint len = usbd_ep_read_packet(dev, 0x01, buf, 8); - debug_printf("USB: Host sent %u bytes\n", len); - if (len >= 5) { - for (uint i=0; i<4; i++) { - disp[i] &= 0x01; - if (buf[i] < 16) - disp[i] |= disp_font[buf[i]]; - } - disp[1] &= 0xfe; - if (buf[4]) - disp[1] |= 0x01; - display_update(); - disp_alive = 10; - } -} - -static void ep82_send(u32 key_code) -{ - if (usb_tx_in_flight) { - debug_printf("USB: Send overrun!\n"); - return; - } - - debug_printf("USB: Sending key to host\n"); - put_u32_be(ep82_tx_buffer, key_code); - usbd_ep_write_packet(usbd_dev, 0x82, ep82_tx_buffer, 4); - usb_tx_in_flight = true; -} - -static void ep82_cb(usbd_device *dev UNUSED, uint8_t ep UNUSED) -{ - // We completed sending a frame to the USB host - usb_tx_in_flight = false; - debug_printf("USB: Key sending complete\n"); -} - -static void set_config_cb(usbd_device *dev, uint16_t wValue UNUSED) -{ - usbd_register_control_callback( - dev, - USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, - USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, - dfu_control_cb); - usbd_ep_setup(dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, ep01_cb); - usbd_ep_setup(dev, 0x82, USB_ENDPOINT_ATTR_BULK, 4, ep82_cb); - usb_configured = true; -} - -static void reset_cb(void) -{ - debug_printf("USB: Reset\n"); - usb_configured = false; -} - -static volatile bool usb_event_pending; - -void usb_lp_can_rx0_isr(void) -{ - /* - * We handle USB in the main loop to avoid race conditions between - * USB interrupts and other code. However, we need an interrupt to - * up the main loop from sleep. - * - * We set up only the low-priority ISR, because high-priority ISR handles - * only double-buffered bulk transfers and isochronous transfers. - */ - nvic_disable_irq(NVIC_USB_LP_CAN_RX0_IRQ); - usb_event_pending = 1; -} - -static void usb_init(void) -{ - // Simulate USB disconnect - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO11 | GPIO12); - gpio_clear(GPIOA, GPIO11 | GPIO12); - delay_ms(100); - - usbd_dev = usbd_init( - &st_usbfs_v1_usb_driver, - &device, - &config, - usb_strings, - ARRAY_SIZE(usb_strings), - usbd_control_buffer, - sizeof(usbd_control_buffer) - ); - usbd_register_reset_callback(usbd_dev, reset_cb); - usbd_register_set_config_callback(usbd_dev, set_config_cb); - usb_event_pending = 1; -} - -/*** Main ***/ - -int main(void) -{ - clock_init(); - gpio_init(); - usart_init(); - - tick_init(); - desig_get_unique_id_as_dfu(usb_serial_number); - - debug_printf("Hello, world!\n"); - - usb_init(); - display_init(); - ir_init(); - - u32 last_blink = 0; - - for (;;) { - if (ms_ticks - last_blink >= 500) { - debug_led_toggle(); - last_blink = ms_ticks; - if (disp_alive) { - if (!--disp_alive) { - disp[0] = (disp[0] & 0x01) | 0x10; - disp[1] = (disp[1] & 0x01) | 0x10; - disp[2] = (disp[2] & 0x01) | 0x10; - disp[3] = (disp[3] & 0x01) | 0x10; - } - } - display_update(); - } - - if ((disp[3] & 0x01) && ms_ticks - ir_blink_start >= 100) { - disp[3] &= 0xfe; - display_update(); - } - - ir_decode(); - - if (usb_event_pending) { - usbd_poll(usbd_dev); - usb_event_pending = 0; - nvic_clear_pending_irq(NVIC_USB_LP_CAN_RX0_IRQ); - nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); - } - - wait_for_interrupt(); - } - - return 0; -}