From bdbd7d68d96fd1a05df58b3e5feeb631f84e0db0 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Mon, 2 Sep 2024 18:21:41 +0300 Subject: [PATCH] hide deprecated code; make USB snippet common for F0/F1/F3 --- .../stm32-backups/stm32-2022-07-07_172626.zip | Bin 96188 -> 0 bytes .../stm32-backups/stm32-2022-07-07_180306.zip | Bin 135138 -> 0 bytes F0:F030,F042,F072/Readme.md | 9 +- .../stm32-backups/stm32-2022-07-07_172440.zip | Bin 52711 -> 0 bytes .../CANbus_stepper/CANbus_stepper.tgz | Bin .../{ => deprecated}/CANbus_stepper/TODO | 0 .../CANbus_stepper/kicad/Readme.md | 0 .../CANbus_stepper/kicad/acs712.lib | 0 .../CANbus_stepper/kicad/elements.lib | 0 .../CANbus_stepper/kicad/fp-info-cache | 0 .../CANbus_stepper/kicad/fp-lib-table | 0 .../kicad/gerbers/stm32-B_Cu.gbr | 0 .../kicad/gerbers/stm32-B_Mask.gbr | 0 .../kicad/gerbers/stm32-B_SilkS.gbr | 0 .../kicad/gerbers/stm32-Edge_Cuts.gbr | 0 .../kicad/gerbers/stm32-F_Cu.gbr | 0 .../kicad/gerbers/stm32-F_Mask.gbr | 0 .../kicad/gerbers/stm32-F_SilkS.gbr | 0 .../kicad/gerbers/stm32-drl_map.gbr | 0 .../my_footprints.pretty/FuseHolder.kicad_mod | 0 .../my_footprints.pretty/Hole_3mm.kicad_mod | 0 .../my_footprints.pretty/RJ9-4P4C.kicad_mod | 0 .../SMD_conn_4x2.5mm.kicad_mod | 0 .../my_footprints.pretty/TH_via.kicad_mod | 0 .../CANbus_stepper/kicad/stm32-rescue.lib | 0 .../CANbus_stepper/kicad/stm32.csv | 0 .../CANbus_stepper/kicad/stm32.kicad_pcb | 0 .../CANbus_stepper/kicad/stm32.kicad_prl | 0 .../CANbus_stepper/kicad/stm32.kicad_pro | 0 .../CANbus_stepper/kicad/stm32.kicad_sch | 0 .../CANbus_stepper/kicad/stm32.net | 0 .../CANbus_stepper/kicad/stm32.pro | 0 .../CANbus_stepper/kicad/stm32.sch | 0 .../CANbus_stepper/kicad/stm32.xml | 0 .../CANbus_stepper/kicad/sym-lib-table | 0 .../{ => deprecated}/CANbus_stepper/src.tgz | Bin .../CANbus_stepper/src/Makefile | 0 .../CANbus_stepper/src/Readme.md | 0 .../{ => deprecated}/CANbus_stepper/src/adc.c | 0 .../{ => deprecated}/CANbus_stepper/src/adc.h | 0 .../{ => deprecated}/CANbus_stepper/src/can.c | 0 .../{ => deprecated}/CANbus_stepper/src/can.h | 0 .../CANbus_stepper/src/can_process.c | 0 .../CANbus_stepper/src/can_process.h | 0 .../CANbus_stepper/src/canstepper.bin | Bin .../CANbus_stepper/src/flash.c | 0 .../CANbus_stepper/src/flash.h | 0 .../CANbus_stepper/src/hardware.c | 0 .../CANbus_stepper/src/hardware.h | 0 .../CANbus_stepper/src/main.c | 0 .../CANbus_stepper/src/proto.c | 0 .../CANbus_stepper/src/proto.h | 0 .../{ => deprecated}/CANbus_stepper/src/spi.c | 0 .../{ => deprecated}/CANbus_stepper/src/spi.h | 0 .../CANbus_stepper/src/steppers.c | 0 .../CANbus_stepper/src/steppers.h | 0 .../CANbus_stepper/src/usart.c | 0 .../CANbus_stepper/src/usart.h | 0 .../{ => deprecated}/CANbus_stepper/src/usb.c | 0 .../{ => deprecated}/CANbus_stepper/src/usb.h | 0 .../CANbus_stepper/src/usb_defs.h | 0 .../CANbus_stepper/src/usb_lib.c | 0 .../CANbus_stepper/src/usb_lib.h | 0 F0:F030,F042,F072/deprecated/Readme.md | 10 + .../USB_pl2303_snippet/Makefile | 0 .../USB_pl2303_snippet/Readme | 0 .../USB_pl2303_snippet/hardware.c | 0 .../USB_pl2303_snippet/hardware.h | 0 .../USB_pl2303_snippet/main.c | 0 .../USB_pl2303_snippet/proto.c | 0 .../USB_pl2303_snippet/proto.h | 0 .../USB_pl2303_snippet/usb.bin | Bin .../{ => deprecated}/USB_pl2303_snippet/usb.c | 0 .../{ => deprecated}/USB_pl2303_snippet/usb.h | 0 .../USB_pl2303_snippet/usb_defs.h | 0 .../USB_pl2303_snippet/usb_lib.c | 0 .../USB_pl2303_snippet/usb_lib.h | 0 .../{ => deprecated}/canbus/kicad/acs712.lib | 0 .../{ => deprecated}/canbus/kicad/bom.ini | 0 .../canbus/kicad/elements.lib | 0 .../canbus/kicad/fp-info-cache | 0 .../canbus/kicad/fp-lib-table | 0 .../my_footprints.pretty/Hole_3mm.kicad_mod | 0 .../my_footprints.pretty/RJ9-4P4C.kicad_mod | 0 .../SMD_conn_4x2.5mm.kicad_mod | 0 .../my_footprints.pretty/TH_via.kicad_mod | 0 .../canbus/kicad/stm32-rescue.lib | 0 .../canbus/kicad/stm32.kicad_pcb | 0 .../canbus/kicad/stm32.kicad_prl | 0 .../canbus/kicad/stm32.kicad_pro | 0 .../canbus/kicad/stm32.kicad_sch | 0 .../{ => deprecated}/canbus/kicad/stm32.net | 0 .../canbus/kicad/sym-lib-table | 0 .../{ => deprecated}/canbus/src/CANbus.geany | 0 .../{ => deprecated}/canbus/src/Makefile | 0 .../{ => deprecated}/canbus/src/can.c | 0 .../{ => deprecated}/canbus/src/can.h | 0 .../{ => deprecated}/canbus/src/canbus.bin | Bin .../{ => deprecated}/canbus/src/canbus.c.tags | 0 .../{ => deprecated}/canbus/src/hardware.c | 0 .../{ => deprecated}/canbus/src/hardware.h | 0 .../{ => deprecated}/canbus/src/main.c | 0 .../{ => deprecated}/canbus/src/usart.c | 0 .../{ => deprecated}/canbus/src/usart.h | 0 .../{ => deprecated}/pl2303/Makefile | 0 .../{ => deprecated}/pl2303/Readme.md | 0 .../{ => deprecated}/pl2303/hardware.c | 0 .../{ => deprecated}/pl2303/hardware.h | 0 .../{ => deprecated}/pl2303/main.c | 0 .../{ => deprecated}/pl2303/pl2303.bin | Bin .../{ => deprecated}/pl2303/usart.c | 0 .../{ => deprecated}/pl2303/usart.h | 0 .../{ => deprecated}/pl2303/usb.c | 0 .../{ => deprecated}/pl2303/usb.h | 0 .../{ => deprecated}/pl2303/usb_defs.h | 0 .../{ => deprecated}/pl2303/usb_lib.c | 0 .../{ => deprecated}/pl2303/usb_lib.h | 0 .../{ => deprecated}/usbcan/Makefile | 0 .../{ => deprecated}/usbcan/Makefile.old | 0 .../{ => deprecated}/usbcan/Readme.md | 0 .../{ => deprecated}/usbcan/can.c | 0 .../{ => deprecated}/usbcan/can.h | 0 .../{ => deprecated}/usbcan/hardware.c | 0 .../{ => deprecated}/usbcan/hardware.h | 0 .../{ => deprecated}/usbcan/kicad/bom.ini | 0 .../usbcan/kicad/elements.lib | 0 .../usbcan/kicad/fp-info-cache | 0 .../usbcan/kicad/fp-lib-table | 0 .../usbcan/kicad/gerbers/stm32-B_Cu.gbr | 0 .../usbcan/kicad/gerbers/stm32-B_Mask.gbr | 0 .../usbcan/kicad/gerbers/stm32-B_SilkS.gbr | 0 .../usbcan/kicad/gerbers/stm32-Edge_Cuts.gbr | 0 .../usbcan/kicad/gerbers/stm32-F_Cu.gbr | 0 .../usbcan/kicad/gerbers/stm32-F_Mask.gbr | 0 .../usbcan/kicad/gerbers/stm32-F_SilkS.gbr | 0 .../usbcan/kicad/gerbers/stm32-drl_map.gbr | 0 .../my_footprints.pretty/B0x0xS.kicad_mod | 0 .../my_footprints.pretty/Hole_3mm.kicad_mod | 0 .../usbcan/kicad/stm32-rescue.lib | 0 .../{ => deprecated}/usbcan/kicad/stm32.csv | 0 .../usbcan/kicad/stm32.kicad_pcb | 0 .../usbcan/kicad/stm32.kicad_prl | 0 .../usbcan/kicad/stm32.kicad_pro | 0 .../{ => deprecated}/usbcan/kicad/stm32.net | 0 .../{ => deprecated}/usbcan/kicad/stm32.pro | 0 .../{ => deprecated}/usbcan/kicad/stm32.sch | 0 .../usbcan/kicad/sym-lib-table | 0 .../usbcan/kicad_new/Back.jpg | Bin .../usbcan/kicad_new/Front.jpg | Bin .../{ => deprecated}/usbcan/kicad_new/bom.ini | 0 .../usbcan/kicad_new/elements.lib | 0 .../usbcan/kicad_new/fp-info-cache | 0 .../usbcan/kicad_new/fp-lib-table | 0 .../usbcan/kicad_new/gerbers/stm32-B_Cu.gbr | 0 .../usbcan/kicad_new/gerbers/stm32-B_Mask.gbr | 0 .../kicad_new/gerbers/stm32-B_Silkscreen.gbr | 0 .../kicad_new/gerbers/stm32-Edge_Cuts.gbr | 0 .../usbcan/kicad_new/gerbers/stm32-F_Cu.gbr | 0 .../usbcan/kicad_new/gerbers/stm32-F_Mask.gbr | 0 .../kicad_new/gerbers/stm32-F_Silkscreen.gbr | 0 .../kicad_new/gerbers/stm32-drl_map.gbr | 0 .../usbcan/kicad_new/gerbers/stm32.drl | 0 .../my_footprints.pretty/B0x0xS.kicad_mod | 0 .../my_footprints.pretty/Hole_3mm.kicad_mod | 0 .../usbcan/kicad_new/stm32-rescue.lib | 0 .../usbcan/kicad_new/stm32.csv | 0 .../usbcan/kicad_new/stm32.kicad_pcb | 0 .../usbcan/kicad_new/stm32.kicad_prl | 0 .../usbcan/kicad_new/stm32.kicad_pro | 0 .../usbcan/kicad_new/stm32.kicad_sch | 0 .../usbcan/kicad_new/stm32.net | 0 .../usbcan/kicad_new/stm32.pdf | Bin .../usbcan/kicad_new/stm32.pro | 0 .../usbcan/kicad_new/stm32.sch | 0 .../usbcan/kicad_new/stm32.xml | 0 .../usbcan/kicad_new/sym-lib-table | 0 .../{ => deprecated}/usbcan/main.c | 0 .../{ => deprecated}/usbcan/proto.c | 0 .../{ => deprecated}/usbcan/proto.h | 0 .../{ => deprecated}/usbcan/usb.c | 0 .../{ => deprecated}/usbcan/usb.h | 0 .../{ => deprecated}/usbcan/usb_defs.h | 0 .../{ => deprecated}/usbcan/usb_lib.c | 0 .../{ => deprecated}/usbcan/usb_lib.h | 0 .../{ => deprecated}/usbcan/usbcan.bin | Bin .../{ => deprecated}/usbcan/version.inc | 0 .../stm32-backups/stm32-2021-04-10_184318.zip | Bin 38683 -> 0 bytes .../stm32-backups/stm32-2021-04-11_222546.zip | Bin 38683 -> 0 bytes F0:F030,F042,F072/usbcan_ringbuffer/Makefile | 6 +- F0:F030,F042,F072/usbcan_ringbuffer/can.c | 13 +- F0:F030,F042,F072/usbcan_ringbuffer/can.h | 1 + F0:F030,F042,F072/usbcan_ringbuffer/main.c | 1 + F0:F030,F042,F072/usbcan_ringbuffer/proto.c | 13 +- .../usbcan_ringbuffer/ringbuffer.c | 119 ++-- .../usbcan_ringbuffer/ringbuffer.h | 16 +- F0:F030,F042,F072/usbcan_ringbuffer/usb.c | 89 +-- F0:F030,F042,F072/usbcan_ringbuffer/usb.h | 5 +- F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.c | 134 ++++- F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.h | 6 +- .../usbcan_ringbuffer/usbcan.bin | Bin 11392 -> 11600 bytes .../usbcan_ringbuffer/usbcanrb.creator.user | 40 +- F0:F030,F042,F072/usbcan_ringbuffer/usbhw.c | 120 +--- F0:F030,F042,F072/usbcan_ringbuffer/usbhw.h | 52 +- .../usbcan_ringbuffer/version.inc | 4 +- F1:F103/PL2303_rb_strip/Makefile | 10 + F1:F103/PL2303_rb_strip/PL2303.bin | Bin 0 -> 5476 bytes F1:F103/PL2303_rb_strip/hardware.c | 36 ++ F1:F103/PL2303_rb_strip/hardware.h | 40 ++ F1:F103/PL2303_rb_strip/main.c | 54 ++ F1:F103/PL2303_rb_strip/openocd.cfg | 4 + F1:F103/PL2303_rb_strip/pl2303.cflags | 1 + F1:F103/PL2303_rb_strip/pl2303.config | 6 + F1:F103/PL2303_rb_strip/pl2303.creator | 1 + F1:F103/PL2303_rb_strip/pl2303.creator.user | 181 ++++++ F1:F103/PL2303_rb_strip/pl2303.cxxflags | 1 + F1:F103/PL2303_rb_strip/pl2303.files | 13 + F1:F103/PL2303_rb_strip/pl2303.includes | 6 + F1:F103/PL2303_rb_strip/proto.c | 263 +++++++++ F1:F103/PL2303_rb_strip/proto.h | 31 + F1:F103/PL2303_rb_strip/ringbuffer.c | 167 ++++++ F1:F103/PL2303_rb_strip/ringbuffer.h | 41 ++ F1:F103/PL2303_rb_strip/usb.c | 135 +++++ F1:F103/PL2303_rb_strip/usb.h | 48 ++ F1:F103/PL2303_rb_strip/usb_lib.c | 550 ++++++++++++++++++ F1:F103/PL2303_rb_strip/usb_lib.h | 172 ++++++ F1:F103/PL2303_rb_strip/usbhw.c | 63 ++ F1:F103/PL2303_rb_strip/usbhw.h | 155 +++++ F1:F103/PL2303_rb_strip/version.inc | 2 + F1:F103/PL2303_ringbuffer/Makefile | 3 +- F1:F103/PL2303_ringbuffer/PL2303.bin | Bin 6672 -> 6884 bytes F1:F103/PL2303_ringbuffer/hardware.c | 4 +- F1:F103/PL2303_ringbuffer/hardware.h | 9 +- F1:F103/PL2303_ringbuffer/main.c | 4 +- F1:F103/PL2303_ringbuffer/pl2303.creator.user | 52 +- F1:F103/PL2303_ringbuffer/proto.c | 3 +- F1:F103/PL2303_ringbuffer/ringbuffer.c | 117 ++-- F1:F103/PL2303_ringbuffer/ringbuffer.h | 12 +- F1:F103/PL2303_ringbuffer/usart.h | 10 - F1:F103/PL2303_ringbuffer/usb.c | 85 +-- F1:F103/PL2303_ringbuffer/usb.h | 9 +- F1:F103/PL2303_ringbuffer/usb_lib.c | 136 ++++- F1:F103/PL2303_ringbuffer/usb_lib.h | 8 +- F1:F103/PL2303_ringbuffer/usbhw.c | 120 +--- F1:F103/PL2303_ringbuffer/usbhw.h | 62 +- F1:F103/PL2303_ringbuffer/version.inc | 4 +- F1:F103/Readme.md | 10 +- F1:F103/STM32F103C.md | 2 +- F1:F103/{ => deprecated}/CDC_ACM/Makefile | 0 F1:F103/{ => deprecated}/CDC_ACM/Readme | 0 F1:F103/{ => deprecated}/CDC_ACM/cdcacm.bin | Bin F1:F103/{ => deprecated}/CDC_ACM/hardware.c | 0 F1:F103/{ => deprecated}/CDC_ACM/hardware.h | 0 F1:F103/{ => deprecated}/CDC_ACM/main.c | 0 F1:F103/{ => deprecated}/CDC_ACM/proto.c | 0 F1:F103/{ => deprecated}/CDC_ACM/proto.h | 0 F1:F103/{ => deprecated}/CDC_ACM/usb.c | 0 F1:F103/{ => deprecated}/CDC_ACM/usb.h | 0 F1:F103/{ => deprecated}/CDC_ACM/usb_defs.h | 0 F1:F103/{ => deprecated}/CDC_ACM/usb_lib.c | 0 F1:F103/{ => deprecated}/CDC_ACM/usb_lib.h | 0 .../{ => deprecated}/MLX90640/MLX90640.bin | Bin F1:F103/{ => deprecated}/MLX90640/Makefile | 0 F1:F103/{ => deprecated}/MLX90640/Readme | 0 F1:F103/{ => deprecated}/MLX90640/hardware.c | 0 F1:F103/{ => deprecated}/MLX90640/hardware.h | 0 F1:F103/{ => deprecated}/MLX90640/i2c.c | 0 F1:F103/{ => deprecated}/MLX90640/i2c.h | 0 F1:F103/{ => deprecated}/MLX90640/main.c | 0 F1:F103/{ => deprecated}/MLX90640/mlx90640.c | 0 F1:F103/{ => deprecated}/MLX90640/mlx90640.h | 0 .../{ => deprecated}/MLX90640/mlx90640_regs.h | 0 F1:F103/{ => deprecated}/MLX90640/proto.c | 0 F1:F103/{ => deprecated}/MLX90640/proto.h | 0 F1:F103/{ => deprecated}/MLX90640/strfunct.c | 0 F1:F103/{ => deprecated}/MLX90640/strfunct.h | 0 F1:F103/{ => deprecated}/MLX90640/usb.c | 0 F1:F103/{ => deprecated}/MLX90640/usb.h | 0 F1:F103/{ => deprecated}/MLX90640/usb_defs.h | 0 F1:F103/{ => deprecated}/MLX90640/usb_lib.c | 0 F1:F103/{ => deprecated}/MLX90640/usb_lib.h | 0 F1:F103/{ => deprecated}/MLX90640/version.inc | 0 F1:F103/{ => deprecated}/PL2303/Makefile | 0 F1:F103/{ => deprecated}/PL2303/Readme | 0 F1:F103/{ => deprecated}/PL2303/hardware.c | 0 F1:F103/{ => deprecated}/PL2303/hardware.h | 0 F1:F103/{ => deprecated}/PL2303/main.c | 0 F1:F103/{ => deprecated}/PL2303/pl2303.bin | Bin F1:F103/{ => deprecated}/PL2303/usart.c | 0 F1:F103/{ => deprecated}/PL2303/usart.h | 0 F1:F103/{ => deprecated}/PL2303/usb.c | 0 F1:F103/{ => deprecated}/PL2303/usb.h | 0 F1:F103/{ => deprecated}/PL2303/usb_defs.h | 0 F1:F103/{ => deprecated}/PL2303/usb_lib.c | 0 F1:F103/{ => deprecated}/PL2303/usb_lib.h | 0 F1:F103/deprecated/Readme.md | 7 + F1:F103/{ => deprecated}/chronometer/GPS.c | 0 F1:F103/{ => deprecated}/chronometer/GPS.h | 0 F1:F103/{ => deprecated}/chronometer/Makefile | 0 .../{ => deprecated}/chronometer/Readme.md | 0 .../chronometer/Readme_rus.txt | 0 F1:F103/{ => deprecated}/chronometer/adc.c | 0 F1:F103/{ => deprecated}/chronometer/adc.h | 0 .../{ => deprecated}/chronometer/chrono.bin | Bin F1:F103/{ => deprecated}/chronometer/flash.c | 0 F1:F103/{ => deprecated}/chronometer/flash.h | 0 .../{ => deprecated}/chronometer/hardware.c | 0 .../{ => deprecated}/chronometer/hardware.h | 0 F1:F103/{ => deprecated}/chronometer/lidar.c | 0 F1:F103/{ => deprecated}/chronometer/lidar.h | 0 F1:F103/{ => deprecated}/chronometer/main.c | 0 .../chronometer/stm32F103xB.ld | 0 F1:F103/{ => deprecated}/chronometer/str.c | 0 F1:F103/{ => deprecated}/chronometer/str.h | 0 F1:F103/{ => deprecated}/chronometer/time.c | 0 F1:F103/{ => deprecated}/chronometer/time.h | 0 F1:F103/{ => deprecated}/chronometer/usart.c | 0 F1:F103/{ => deprecated}/chronometer/usart.h | 0 F1:F103/{ => deprecated}/chronometer/usb.c | 0 F1:F103/{ => deprecated}/chronometer/usb.h | 0 .../{ => deprecated}/chronometer/usb_defs.h | 0 .../{ => deprecated}/chronometer/usb_lib.c | 0 .../{ => deprecated}/chronometer/usb_lib.h | 0 .../chronometer_v2/Difference | 0 F1:F103/{ => deprecated}/chronometer_v2/GPS.c | 0 F1:F103/{ => deprecated}/chronometer_v2/GPS.h | 0 .../{ => deprecated}/chronometer_v2/Makefile | 0 .../{ => deprecated}/chronometer_v2/Readme.md | 0 .../chronometer_v2/Readme_rus.txt | 0 F1:F103/{ => deprecated}/chronometer_v2/adc.c | 0 F1:F103/{ => deprecated}/chronometer_v2/adc.h | 0 .../chronometer_v2/chrono.bin | Bin .../{ => deprecated}/chronometer_v2/flash.c | 0 .../{ => deprecated}/chronometer_v2/flash.h | 0 .../chronometer_v2/hardware.c | 0 .../chronometer_v2/hardware.h | 0 .../kicad/2019.10.23-22:09:24.png | Bin .../kicad/2019.10.23_22:08:42.png | Bin .../chronometer_v2/kicad/Chrono.lib | 0 .../chronometer_v2/kicad/chrono | 0 .../chronometer_v2/kicad/chrono.kicad_pcb | 0 .../chronometer_v2/kicad/chrono.kicad_prl | 0 .../chronometer_v2/kicad/chrono.kicad_pro | 0 .../chronometer_v2/kicad/chrono.kicad_sch | 0 .../chronometer_v2/kicad/chrono.net | 0 .../kicad/chrono.pretty/L80-R.kicad_mod | 0 .../chronometer_v2/kicad/chrono.pro | 0 .../chronometer_v2/kicad/chrono.sch | 0 .../chronometer_v2/kicad/fp-info-cache | 0 .../chronometer_v2/kicad/fp-lib-table | 0 .../kicad/gerbers/chrono-B_Cu.gbr | 0 .../kicad/gerbers/chrono-B_Mask.gbr | 0 .../kicad/gerbers/chrono-B_SilkS.gbr | 0 .../kicad/gerbers/chrono-Edge_Cuts.gbr | 0 .../kicad/gerbers/chrono-F_Cu.gbr | 0 .../kicad/gerbers/chrono-F_Mask.gbr | 0 .../kicad/gerbers/chrono-F_SilkS.gbr | 0 .../chronometer_v2/kicad/stm32-rescue.lib | 0 .../chronometer_v2/kicad/sym-lib-table | 0 .../{ => deprecated}/chronometer_v2/lidar.c | 0 .../{ => deprecated}/chronometer_v2/lidar.h | 0 .../{ => deprecated}/chronometer_v2/main.c | 0 .../chronometer_v2/stm32F103xB.ld | 0 F1:F103/{ => deprecated}/chronometer_v2/str.c | 0 F1:F103/{ => deprecated}/chronometer_v2/str.h | 0 .../{ => deprecated}/chronometer_v2/time.c | 0 .../{ => deprecated}/chronometer_v2/time.h | 0 .../{ => deprecated}/chronometer_v2/usart.c | 0 .../{ => deprecated}/chronometer_v2/usart.h | 0 F1:F103/{ => deprecated}/chronometer_v2/usb.c | 0 F1:F103/{ => deprecated}/chronometer_v2/usb.h | 0 .../chronometer_v2/usb_defs.h | 0 .../{ => deprecated}/chronometer_v2/usb_lib.c | 0 .../{ => deprecated}/chronometer_v2/usb_lib.h | 0 .../{ => deprecated}/pl2303_snippet/Makefile | 0 .../{ => deprecated}/pl2303_snippet/Readme | 0 .../pl2303_snippet/hardware.c | 0 .../pl2303_snippet/hardware.h | 0 .../{ => deprecated}/pl2303_snippet/main.c | 0 .../pl2303_snippet/pl2303.bin | Bin .../{ => deprecated}/pl2303_snippet/proto.c | 0 .../{ => deprecated}/pl2303_snippet/proto.h | 0 F1:F103/{ => deprecated}/pl2303_snippet/usb.c | 0 F1:F103/{ => deprecated}/pl2303_snippet/usb.h | 0 .../pl2303_snippet/usb_defs.h | 0 .../{ => deprecated}/pl2303_snippet/usb_lib.c | 0 .../{ => deprecated}/pl2303_snippet/usb_lib.h | 0 .../pl2303_snippet_naked/Makefile | 0 .../pl2303_snippet_naked/Readme | 0 .../pl2303_snippet_naked/hardware.c | 0 .../pl2303_snippet_naked/hardware.h | 0 .../pl2303_snippet_naked/main.c | 0 .../pl2303_snippet_naked/pl2303.bin | Bin .../pl2303_snippet_naked/proto.c | 0 .../pl2303_snippet_naked/proto.h | 0 .../pl2303_snippet_naked/usb.c | 0 .../pl2303_snippet_naked/usb.h | 0 .../pl2303_snippet_naked/usb_defs.h | 0 .../pl2303_snippet_naked/usb_lib.c | 0 .../pl2303_snippet_naked/usb_lib.h | 0 F3:F303/Multistepper/multistepper.bin | Bin 44920 -> 44872 bytes .../Multistepper/multistepper.creator.user | 2 +- F3:F303/Multistepper/ringbuffer.c | 1 - F3:F303/Multistepper/ringbuffer.h | 7 +- F3:F303/Multistepper/usb.c | 11 +- F3:F303/Multistepper/usb.h | 1 - F3:F303/Multistepper/usb_lib.c | 108 +++- F3:F303/Multistepper/usb_lib.h | 13 +- F3:F303/Multistepper/usbhw.c | 112 +--- F3:F303/Multistepper/usbhw.h | 48 +- F3:F303/Multistepper/version.inc | 4 +- snippets/usb_pl2303/Readme | 10 +- snippets/usb_pl2303/ringbuffer.c | 167 ++++++ snippets/usb_pl2303/ringbuffer.h | 41 ++ snippets/usb_pl2303/usb.c | 85 +-- snippets/usb_pl2303/usb.h | 5 +- snippets/usb_pl2303/usb_lib.c | 136 ++++- snippets/usb_pl2303/usb_lib.h | 7 +- snippets/usb_pl2303/usbhw.c | 114 +--- snippets/usb_pl2303/usbhw.h | 50 +- 419 files changed, 3445 insertions(+), 752 deletions(-) delete mode 100644 F0:F030,F042,F072/CANbus_stepper/kicad/stm32-backups/stm32-2022-07-07_172626.zip delete mode 100644 F0:F030,F042,F072/CANbus_stepper/kicad/stm32-backups/stm32-2022-07-07_180306.zip delete mode 100644 F0:F030,F042,F072/canbus/kicad/stm32-backups/stm32-2022-07-07_172440.zip rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/CANbus_stepper.tgz (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/TODO (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/Readme.md (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/acs712.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/elements.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/fp-info-cache (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/fp-lib-table (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/gerbers/stm32-B_Cu.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/gerbers/stm32-B_Mask.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/gerbers/stm32-B_SilkS.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/gerbers/stm32-Edge_Cuts.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/gerbers/stm32-F_Cu.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/gerbers/stm32-F_Mask.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/gerbers/stm32-F_SilkS.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/gerbers/stm32-drl_map.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/my_footprints.pretty/FuseHolder.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/my_footprints.pretty/Hole_3mm.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/my_footprints.pretty/RJ9-4P4C.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/my_footprints.pretty/SMD_conn_4x2.5mm.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/my_footprints.pretty/TH_via.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32-rescue.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32.csv (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32.kicad_pcb (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32.kicad_prl (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32.kicad_pro (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32.kicad_sch (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32.net (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32.pro (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32.sch (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/stm32.xml (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/kicad/sym-lib-table (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src.tgz (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/Makefile (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/Readme.md (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/adc.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/adc.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/can.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/can.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/can_process.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/can_process.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/canstepper.bin (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/flash.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/flash.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/hardware.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/hardware.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/main.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/proto.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/proto.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/spi.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/spi.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/steppers.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/steppers.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/usart.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/usart.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/usb.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/usb.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/usb_defs.h (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/usb_lib.c (100%) rename F0:F030,F042,F072/{ => deprecated}/CANbus_stepper/src/usb_lib.h (100%) create mode 100644 F0:F030,F042,F072/deprecated/Readme.md rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/Makefile (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/Readme (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/hardware.c (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/hardware.h (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/main.c (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/proto.c (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/proto.h (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/usb.bin (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/usb.c (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/usb.h (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/usb_defs.h (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/usb_lib.c (100%) rename F0:F030,F042,F072/{ => deprecated}/USB_pl2303_snippet/usb_lib.h (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/acs712.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/bom.ini (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/elements.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/fp-info-cache (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/fp-lib-table (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/my_footprints.pretty/Hole_3mm.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/my_footprints.pretty/RJ9-4P4C.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/my_footprints.pretty/SMD_conn_4x2.5mm.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/my_footprints.pretty/TH_via.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/stm32-rescue.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/stm32.kicad_pcb (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/stm32.kicad_prl (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/stm32.kicad_pro (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/stm32.kicad_sch (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/stm32.net (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/kicad/sym-lib-table (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/CANbus.geany (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/Makefile (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/can.c (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/can.h (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/canbus.bin (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/canbus.c.tags (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/hardware.c (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/hardware.h (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/main.c (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/usart.c (100%) rename F0:F030,F042,F072/{ => deprecated}/canbus/src/usart.h (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/Makefile (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/Readme.md (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/hardware.c (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/hardware.h (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/main.c (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/pl2303.bin (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/usart.c (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/usart.h (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/usb.c (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/usb.h (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/usb_defs.h (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/usb_lib.c (100%) rename F0:F030,F042,F072/{ => deprecated}/pl2303/usb_lib.h (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/Makefile (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/Makefile.old (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/Readme.md (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/can.c (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/can.h (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/hardware.c (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/hardware.h (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/bom.ini (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/elements.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/fp-info-cache (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/fp-lib-table (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/gerbers/stm32-B_Cu.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/gerbers/stm32-B_Mask.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/gerbers/stm32-B_SilkS.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/gerbers/stm32-Edge_Cuts.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/gerbers/stm32-F_Cu.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/gerbers/stm32-F_Mask.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/gerbers/stm32-F_SilkS.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/gerbers/stm32-drl_map.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/my_footprints.pretty/B0x0xS.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/my_footprints.pretty/Hole_3mm.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/stm32-rescue.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/stm32.csv (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/stm32.kicad_pcb (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/stm32.kicad_prl (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/stm32.kicad_pro (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/stm32.net (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/stm32.pro (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/stm32.sch (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad/sym-lib-table (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/Back.jpg (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/Front.jpg (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/bom.ini (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/elements.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/fp-info-cache (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/fp-lib-table (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/gerbers/stm32-B_Cu.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/gerbers/stm32-B_Mask.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/gerbers/stm32-B_Silkscreen.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/gerbers/stm32-Edge_Cuts.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/gerbers/stm32-F_Cu.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/gerbers/stm32-F_Mask.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/gerbers/stm32-F_Silkscreen.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/gerbers/stm32-drl_map.gbr (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/gerbers/stm32.drl (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/my_footprints.pretty/B0x0xS.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/my_footprints.pretty/Hole_3mm.kicad_mod (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32-rescue.lib (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.csv (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.kicad_pcb (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.kicad_prl (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.kicad_pro (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.kicad_sch (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.net (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.pdf (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.pro (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.sch (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/stm32.xml (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/kicad_new/sym-lib-table (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/main.c (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/proto.c (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/proto.h (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/usb.c (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/usb.h (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/usb_defs.h (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/usb_lib.c (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/usb_lib.h (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/usbcan.bin (100%) rename F0:F030,F042,F072/{ => deprecated}/usbcan/version.inc (100%) delete mode 100644 F0:F030,F042,F072/usbcan/kicad/stm32-backups/stm32-2021-04-10_184318.zip delete mode 100644 F0:F030,F042,F072/usbcan/kicad/stm32-backups/stm32-2021-04-11_222546.zip create mode 100644 F1:F103/PL2303_rb_strip/Makefile create mode 100755 F1:F103/PL2303_rb_strip/PL2303.bin create mode 100644 F1:F103/PL2303_rb_strip/hardware.c create mode 100644 F1:F103/PL2303_rb_strip/hardware.h create mode 100644 F1:F103/PL2303_rb_strip/main.c create mode 100644 F1:F103/PL2303_rb_strip/openocd.cfg create mode 100644 F1:F103/PL2303_rb_strip/pl2303.cflags create mode 100644 F1:F103/PL2303_rb_strip/pl2303.config create mode 100644 F1:F103/PL2303_rb_strip/pl2303.creator create mode 100644 F1:F103/PL2303_rb_strip/pl2303.creator.user create mode 100644 F1:F103/PL2303_rb_strip/pl2303.cxxflags create mode 100644 F1:F103/PL2303_rb_strip/pl2303.files create mode 100644 F1:F103/PL2303_rb_strip/pl2303.includes create mode 100644 F1:F103/PL2303_rb_strip/proto.c create mode 100644 F1:F103/PL2303_rb_strip/proto.h create mode 100644 F1:F103/PL2303_rb_strip/ringbuffer.c create mode 100644 F1:F103/PL2303_rb_strip/ringbuffer.h create mode 100644 F1:F103/PL2303_rb_strip/usb.c create mode 100644 F1:F103/PL2303_rb_strip/usb.h create mode 100644 F1:F103/PL2303_rb_strip/usb_lib.c create mode 100644 F1:F103/PL2303_rb_strip/usb_lib.h create mode 100644 F1:F103/PL2303_rb_strip/usbhw.c create mode 100644 F1:F103/PL2303_rb_strip/usbhw.h create mode 100644 F1:F103/PL2303_rb_strip/version.inc rename F1:F103/{ => deprecated}/CDC_ACM/Makefile (100%) rename F1:F103/{ => deprecated}/CDC_ACM/Readme (100%) rename F1:F103/{ => deprecated}/CDC_ACM/cdcacm.bin (100%) rename F1:F103/{ => deprecated}/CDC_ACM/hardware.c (100%) rename F1:F103/{ => deprecated}/CDC_ACM/hardware.h (100%) rename F1:F103/{ => deprecated}/CDC_ACM/main.c (100%) rename F1:F103/{ => deprecated}/CDC_ACM/proto.c (100%) rename F1:F103/{ => deprecated}/CDC_ACM/proto.h (100%) rename F1:F103/{ => deprecated}/CDC_ACM/usb.c (100%) rename F1:F103/{ => deprecated}/CDC_ACM/usb.h (100%) rename F1:F103/{ => deprecated}/CDC_ACM/usb_defs.h (100%) rename F1:F103/{ => deprecated}/CDC_ACM/usb_lib.c (100%) rename F1:F103/{ => deprecated}/CDC_ACM/usb_lib.h (100%) rename F1:F103/{ => deprecated}/MLX90640/MLX90640.bin (100%) rename F1:F103/{ => deprecated}/MLX90640/Makefile (100%) rename F1:F103/{ => deprecated}/MLX90640/Readme (100%) rename F1:F103/{ => deprecated}/MLX90640/hardware.c (100%) rename F1:F103/{ => deprecated}/MLX90640/hardware.h (100%) rename F1:F103/{ => deprecated}/MLX90640/i2c.c (100%) rename F1:F103/{ => deprecated}/MLX90640/i2c.h (100%) rename F1:F103/{ => deprecated}/MLX90640/main.c (100%) rename F1:F103/{ => deprecated}/MLX90640/mlx90640.c (100%) rename F1:F103/{ => deprecated}/MLX90640/mlx90640.h (100%) rename F1:F103/{ => deprecated}/MLX90640/mlx90640_regs.h (100%) rename F1:F103/{ => deprecated}/MLX90640/proto.c (100%) rename F1:F103/{ => deprecated}/MLX90640/proto.h (100%) rename F1:F103/{ => deprecated}/MLX90640/strfunct.c (100%) rename F1:F103/{ => deprecated}/MLX90640/strfunct.h (100%) rename F1:F103/{ => deprecated}/MLX90640/usb.c (100%) rename F1:F103/{ => deprecated}/MLX90640/usb.h (100%) rename F1:F103/{ => deprecated}/MLX90640/usb_defs.h (100%) rename F1:F103/{ => deprecated}/MLX90640/usb_lib.c (100%) rename F1:F103/{ => deprecated}/MLX90640/usb_lib.h (100%) rename F1:F103/{ => deprecated}/MLX90640/version.inc (100%) rename F1:F103/{ => deprecated}/PL2303/Makefile (100%) rename F1:F103/{ => deprecated}/PL2303/Readme (100%) rename F1:F103/{ => deprecated}/PL2303/hardware.c (100%) rename F1:F103/{ => deprecated}/PL2303/hardware.h (100%) rename F1:F103/{ => deprecated}/PL2303/main.c (100%) rename F1:F103/{ => deprecated}/PL2303/pl2303.bin (100%) rename F1:F103/{ => deprecated}/PL2303/usart.c (100%) rename F1:F103/{ => deprecated}/PL2303/usart.h (100%) rename F1:F103/{ => deprecated}/PL2303/usb.c (100%) rename F1:F103/{ => deprecated}/PL2303/usb.h (100%) rename F1:F103/{ => deprecated}/PL2303/usb_defs.h (100%) rename F1:F103/{ => deprecated}/PL2303/usb_lib.c (100%) rename F1:F103/{ => deprecated}/PL2303/usb_lib.h (100%) create mode 100644 F1:F103/deprecated/Readme.md rename F1:F103/{ => deprecated}/chronometer/GPS.c (100%) rename F1:F103/{ => deprecated}/chronometer/GPS.h (100%) rename F1:F103/{ => deprecated}/chronometer/Makefile (100%) rename F1:F103/{ => deprecated}/chronometer/Readme.md (100%) rename F1:F103/{ => deprecated}/chronometer/Readme_rus.txt (100%) rename F1:F103/{ => deprecated}/chronometer/adc.c (100%) rename F1:F103/{ => deprecated}/chronometer/adc.h (100%) rename F1:F103/{ => deprecated}/chronometer/chrono.bin (100%) rename F1:F103/{ => deprecated}/chronometer/flash.c (100%) rename F1:F103/{ => deprecated}/chronometer/flash.h (100%) rename F1:F103/{ => deprecated}/chronometer/hardware.c (100%) rename F1:F103/{ => deprecated}/chronometer/hardware.h (100%) rename F1:F103/{ => deprecated}/chronometer/lidar.c (100%) rename F1:F103/{ => deprecated}/chronometer/lidar.h (100%) rename F1:F103/{ => deprecated}/chronometer/main.c (100%) rename F1:F103/{ => deprecated}/chronometer/stm32F103xB.ld (100%) rename F1:F103/{ => deprecated}/chronometer/str.c (100%) rename F1:F103/{ => deprecated}/chronometer/str.h (100%) rename F1:F103/{ => deprecated}/chronometer/time.c (100%) rename F1:F103/{ => deprecated}/chronometer/time.h (100%) rename F1:F103/{ => deprecated}/chronometer/usart.c (100%) rename F1:F103/{ => deprecated}/chronometer/usart.h (100%) rename F1:F103/{ => deprecated}/chronometer/usb.c (100%) rename F1:F103/{ => deprecated}/chronometer/usb.h (100%) rename F1:F103/{ => deprecated}/chronometer/usb_defs.h (100%) rename F1:F103/{ => deprecated}/chronometer/usb_lib.c (100%) rename F1:F103/{ => deprecated}/chronometer/usb_lib.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/Difference (100%) rename F1:F103/{ => deprecated}/chronometer_v2/GPS.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/GPS.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/Makefile (100%) rename F1:F103/{ => deprecated}/chronometer_v2/Readme.md (100%) rename F1:F103/{ => deprecated}/chronometer_v2/Readme_rus.txt (100%) rename F1:F103/{ => deprecated}/chronometer_v2/adc.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/adc.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/chrono.bin (100%) rename F1:F103/{ => deprecated}/chronometer_v2/flash.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/flash.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/hardware.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/hardware.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/2019.10.23-22:09:24.png (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/2019.10.23_22:08:42.png (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/Chrono.lib (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/chrono (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/chrono.kicad_pcb (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/chrono.kicad_prl (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/chrono.kicad_pro (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/chrono.kicad_sch (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/chrono.net (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/chrono.pretty/L80-R.kicad_mod (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/chrono.pro (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/chrono.sch (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/fp-info-cache (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/fp-lib-table (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/gerbers/chrono-B_Cu.gbr (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/gerbers/chrono-B_Mask.gbr (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/gerbers/chrono-B_SilkS.gbr (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/gerbers/chrono-Edge_Cuts.gbr (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/gerbers/chrono-F_Cu.gbr (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/gerbers/chrono-F_Mask.gbr (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/gerbers/chrono-F_SilkS.gbr (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/stm32-rescue.lib (100%) rename F1:F103/{ => deprecated}/chronometer_v2/kicad/sym-lib-table (100%) rename F1:F103/{ => deprecated}/chronometer_v2/lidar.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/lidar.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/main.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/stm32F103xB.ld (100%) rename F1:F103/{ => deprecated}/chronometer_v2/str.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/str.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/time.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/time.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/usart.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/usart.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/usb.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/usb.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/usb_defs.h (100%) rename F1:F103/{ => deprecated}/chronometer_v2/usb_lib.c (100%) rename F1:F103/{ => deprecated}/chronometer_v2/usb_lib.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/Makefile (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/Readme (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/hardware.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/hardware.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/main.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/pl2303.bin (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/proto.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/proto.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/usb.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/usb.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/usb_defs.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/usb_lib.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet/usb_lib.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/Makefile (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/Readme (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/hardware.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/hardware.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/main.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/pl2303.bin (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/proto.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/proto.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/usb.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/usb.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/usb_defs.h (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/usb_lib.c (100%) rename F1:F103/{ => deprecated}/pl2303_snippet_naked/usb_lib.h (100%) create mode 100644 snippets/usb_pl2303/ringbuffer.c create mode 100644 snippets/usb_pl2303/ringbuffer.h diff --git a/F0:F030,F042,F072/CANbus_stepper/kicad/stm32-backups/stm32-2022-07-07_172626.zip b/F0:F030,F042,F072/CANbus_stepper/kicad/stm32-backups/stm32-2022-07-07_172626.zip deleted file mode 100644 index 4d0f105bd833803c5c9c223060ef1909c4fa1074..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96188 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%0DP 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 diff --git a/F0:F030,F042,F072/usbcan/kicad/stm32-backups/stm32-2021-04-11_222546.zip b/F0:F030,F042,F072/usbcan/kicad/stm32-backups/stm32-2021-04-11_222546.zip deleted file mode 100644 index 5ad754343ee4a37be8785ff079d505c14cb41193..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38683 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%0DP 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 diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/Makefile b/F0:F030,F042,F072/usbcan_ringbuffer/Makefile index 03d8a04..6332bf6 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/Makefile +++ b/F0:F030,F042,F072/usbcan_ringbuffer/Makefile @@ -1,8 +1,10 @@ BINARY := usbcan # MCU code -MCU := F072xB +#MCU := F072xB +MCU := F042x6 # change this linking script depending on particular MCU model, -LDSCRIPT := stm32f072x8.ld +#LDSCRIPT := stm32f072xB.ld +LDSCRIPT := stm32f042x6.ld DEFINES := -DUSB2_16 diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/can.c b/F0:F030,F042,F072/usbcan_ringbuffer/can.c index f136f6f..694e96a 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/can.c +++ b/F0:F030,F042,F072/usbcan_ringbuffer/can.c @@ -111,14 +111,21 @@ so if TBS1=4 and TBS2=3, sum=8, bit sampling freq is 48/8 = 6MHz 1MBps - 6 */ + +static uint16_t oldspeed = 100; // speed of last init +uint16_t CAN_getspeed(){ + return oldspeed; +} // speed - in kbps. @return - current speed int CAN_setup(uint16_t speed){ - static uint16_t oldspeed = 100; // speed of last init LED_off(LED1); + flood_msg = NULL; // clear for not flood in terminal + incrflood = 0; if(speed == 0) speed = oldspeed; else if(speed < 50) speed = 50; else if(speed > 3000) speed = 3000; - oldspeed = speed; + uint32_t regval = 6000/speed - 1; + oldspeed = 6000 / (regval + 1); // new speed due to register value uint32_t tmout = 16000000; // Configure GPIO: PB8 - CAN_Rx, PB9 - CAN_Tx /* (1) Select AF mode (10) on PB8 and PB9 */ @@ -148,7 +155,7 @@ int CAN_setup(uint16_t speed){ CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */ CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */ - CAN->BTR = 2 << 20 | 3 << 16 | (6000/speed - 1); /* (4) */ + CAN->BTR = 2 << 20 | 3 << 16 | regval; /* (4) */ CAN->MCR &=~ CAN_MCR_INRQ; /* (5) */ tmout = 16000000; while((CAN->MSR & CAN_MSR_INAK)==CAN_MSR_INAK) if(--tmout == 0) break; /* (6) */ diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/can.h b/F0:F030,F042,F072/usbcan_ringbuffer/can.h index 4085f84..55d9a6c 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/can.h +++ b/F0:F030,F042,F072/usbcan_ringbuffer/can.h @@ -49,6 +49,7 @@ CAN_status CAN_get_status(); int CAN_reinit(uint16_t speed); int CAN_setup(uint16_t speed); +uint16_t CAN_getspeed(); CAN_status can_send(uint8_t *msg, uint8_t len, uint16_t target_id); void can_proc(); diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/main.c b/F0:F030,F042,F072/usbcan_ringbuffer/main.c index 109b6bb..4f99cb1 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/main.c +++ b/F0:F030,F042,F072/usbcan_ringbuffer/main.c @@ -56,6 +56,7 @@ int main(void){ USB_sendstr("CAN bus fifo overrun occured!\n"); } while((can_mesg = CAN_messagebuf_pop())){ + IWDG->KR = IWDG_REFRESH; if(can_mesg && isgood(can_mesg->ID)){ LED_on(LED0); lastT = Tms; diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/proto.c b/F0:F030,F042,F072/usbcan_ringbuffer/proto.c index e5f5da2..43648fe 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/proto.c +++ b/F0:F030,F042,F072/usbcan_ringbuffer/proto.c @@ -216,14 +216,15 @@ TRUE_INLINE void CANini(char *txt){ uint32_t N; char *n = getnum(txt, &N); if(txt == n){ - USB_sendstr("No speed given"); + printu(CAN_getspeed()); + USB_sendstr("kbps\n"); return; } if(N < 50){ - USB_sendstr("Lowest speed is 50kbps"); + USB_sendstr("Lowest speed is 50kbps\n"); return; }else if(N > 3000){ - USB_sendstr("Highest speed is 3000kbps"); + USB_sendstr("Highest speed is 3000kbps\n"); return; } CAN_reinit((uint16_t)N); @@ -432,7 +433,7 @@ const char *helpmsg = "'b' - reinit CAN with given baudrate\n" "'c' - get CAN status\n" "'d' - delete ignore list\n" - "'D' - activate DFU mode\n" +// "'D' - activate DFU mode\n" "'e' - get CAN errcodes\n" "'f' - add/delete filter, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]\n" "'F' - send/clear flood message: F ID byte0 ... byteN\n" @@ -508,12 +509,12 @@ void cmd_parser(char *txt){ break; case 'e': printCANerr(); - break; + break;/* case 'D': USB_sendstr("Go into DFU mode\n"); USB_sendall(); Jump2Boot(); - break; + break;*/ case 'i': set_flood(NULL, 1); USB_sendstr("Incremental flooding is ON ('F' to off)\n"); diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/ringbuffer.c b/F0:F030,F042,F072/usbcan_ringbuffer/ringbuffer.c index d70a9a7..8d8d6ca 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/ringbuffer.c +++ b/F0:F030,F042,F072/usbcan_ringbuffer/ringbuffer.c @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2022 Edward V. Emelianov . + * Copyright 2023 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,19 +17,21 @@ #include "ringbuffer.h" -// stored data length -int RB_datalen(ringbuffer *b){ +static int datalen(ringbuffer *b){ if(b->tail >= b->head) return (b->tail - b->head); else return (b->length - b->head + b->tail); } -/** - * @brief RB_hasbyte - check if buffer has given byte stored - * @param b - buffer - * @param byte - byte to find - * @return index if found, -1 if none - */ -int RB_hasbyte(ringbuffer *b, uint8_t byte){ +// stored data length +int RB_datalen(ringbuffer *b){ + if(b->busy) return -1; + b->busy = 1; + int l = datalen(b); + b->busy = 0; + return l; +} + +static int hasbyte(ringbuffer *b, uint8_t byte){ if(b->head == b->tail) return -1; // no data in buffer int startidx = b->head; if(b->head > b->tail){ // @@ -43,6 +44,20 @@ int RB_hasbyte(ringbuffer *b, uint8_t byte){ return -1; } +/** + * @brief RB_hasbyte - check if buffer has given byte stored + * @param b - buffer + * @param byte - byte to find + * @return index if found, -1 if none or busy + */ +int RB_hasbyte(ringbuffer *b, uint8_t byte){ + if(b->busy) return -1; + b->busy = 1; + int ret = hasbyte(b, byte); + b->busy = 0; + return ret; +} + // poor memcpy static void mcpy(uint8_t *targ, const uint8_t *src, int l){ while(l--) *targ++ = *src++; @@ -54,15 +69,8 @@ TRUE_INLINE void incr(ringbuffer *b, volatile int *what, int n){ if(*what >= b->length) *what -= b->length; } -/** - * @brief RB_read - read data from ringbuffer - * @param b - buffer - * @param s - array to write data - * @param len - max len of `s` - * @return bytes read - */ -int RB_read(ringbuffer *b, uint8_t *s, int len){ - int l = RB_datalen(b); +static int read(ringbuffer *b, uint8_t *s, int len){ + int l = datalen(b); if(!l) return 0; if(l > len) l = len; int _1st = b->length - b->head; @@ -78,33 +86,49 @@ int RB_read(ringbuffer *b, uint8_t *s, int len){ return _1st; } +/** + * @brief RB_read - read data from ringbuffer + * @param b - buffer + * @param s - array to write data + * @param len - max len of `s` + * @return bytes read or -1 if busy + */ +int RB_read(ringbuffer *b, uint8_t *s, int len){ + if(b->busy) return -1; + b->busy = 1; + int r = read(b, s, len); + b->busy = 0; + return r; +} + +static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){ + int idx = hasbyte(b, byte); + if(idx < 0) return 0; + int partlen = idx + 1 - b->head; + // now calculate length of new data portion + if(idx < b->head) partlen += b->length; + if(partlen > len) return -read(b, s, len); + return read(b, s, partlen); +} + /** * @brief RB_readto fill array `s` with data until byte `byte` (with it) * @param b - ringbuffer * @param byte - check byte * @param s - buffer to write data * @param len - length of `s` - * @return amount of bytes written (negative, if lenhead; - // now calculate length of new data portion - if(idx < b->head) partlen += b->length; - if(partlen > len) return -RB_read(b, s, len); - return RB_read(b, s, partlen); + if(b->busy) return -1; + b->busy = 1; + int n = readto(b, byte, s, len); + b->busy = 0; + return n; } -/** - * @brief RB_write - write some data to ringbuffer - * @param b - buffer - * @param str - data - * @param l - length - * @return amount of bytes written - */ -int RB_write(ringbuffer *b, const uint8_t *str, int l){ - int r = b->length - 1 - RB_datalen(b); // rest length +static int write(ringbuffer *b, const uint8_t *str, int l){ + int r = b->length - 1 - datalen(b); // rest length if(l > r) l = r; if(!l) return 0; int _1st = b->length - b->tail; @@ -117,8 +141,27 @@ int RB_write(ringbuffer *b, const uint8_t *str, int l){ return l; } +/** + * @brief RB_write - write some data to ringbuffer + * @param b - buffer + * @param str - data + * @param l - length + * @return amount of bytes written or -1 if busy + */ +int RB_write(ringbuffer *b, const uint8_t *str, int l){ + if(b->busy) return -1; + b->busy = 1; + int w = write(b, str, l); + b->busy = 0; + return w; +} + // just delete all information in buffer `b` -void RB_clearbuf(ringbuffer *b){ +int RB_clearbuf(ringbuffer *b){ + if(b->busy) return -1; + b->busy = 1; b->head = 0; b->tail = 0; + b->busy = 0; + return 1; } diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/ringbuffer.h b/F0:F030,F042,F072/usbcan_ringbuffer/ringbuffer.h index 2c04863..ed2cf95 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/ringbuffer.h +++ b/F0:F030,F042,F072/usbcan_ringbuffer/ringbuffer.h @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2022 Edward V. Emelianov . + * Copyright 2023 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,16 +16,21 @@ */ #pragma once -#ifndef RINGBUFFER_H__ -#define RINGBUFFER_H__ +#if defined STM32F0 #include +#elif defined STM32F1 +#include +#elif defined STM32F3 +#include +#endif typedef struct{ uint8_t *data; // data buffer const int length; // its length int head; // head index int tail; // tail index + volatile int busy; // == TRUE if buffer is busy now } ringbuffer; int RB_read(ringbuffer *b, uint8_t *s, int len); @@ -34,6 +38,4 @@ int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len); int RB_hasbyte(ringbuffer *b, uint8_t byte); int RB_write(ringbuffer *b, const uint8_t *str, int l); int RB_datalen(ringbuffer *b); -void RB_clearbuf(ringbuffer *b); - -#endif // RINGBUFFER_H__ +int RB_clearbuf(ringbuffer *b); diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/usb.c b/F0:F030,F042,F072/usbcan_ringbuffer/usb.c index 9a83e16..7848e1a 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/usb.c +++ b/F0:F030,F042,F072/usbcan_ringbuffer/usb.c @@ -1,6 +1,5 @@ /* - * This file is part of the usbcanrb project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,18 +26,23 @@ static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending da static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ]; volatile ringbuffer rbout = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0}; volatile ringbuffer rbin = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0}; -// transmission is succesfull -volatile uint8_t bufisempty = 1; +// inbuf overflow when receiving volatile uint8_t bufovrfl = 0; +// last send data size +static volatile int lastdsz = 0; +// called from transmit EP void send_next(){ - if(bufisempty) return; - static int lastdsz = 0; + IWDG->KR = IWDG_REFRESH; int buflen = RB_read((ringbuffer*)&rbout, (uint8_t*)usbbuff, USB_TXBUFSZ); - if(!buflen){ + if(buflen == 0){ if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send lastdsz = 0; - bufisempty = 1; + return; + }else if(buflen < 0){ + lastdsz = 0; + // Uncomment next line if you want 4Mbit/s instead of 6Mbit/s + //EP_Write(3, NULL, 0); // send ZLP if buffer is in writting state now return; } EP_Write(3, (uint8_t*)usbbuff, buflen); @@ -47,44 +51,45 @@ void send_next(){ // blocking send full content of ring buffer int USB_sendall(){ - while(!bufisempty){ - if(!usbON) return 0; + while(lastdsz > 0){ + IWDG->KR = IWDG_REFRESH; + if(!usbON) return FALSE; } - return 1; + return TRUE; } // put `buf` into queue to send int USB_send(const uint8_t *buf, int len){ - if(!buf || !usbON || !len) return 0; + if(!buf || !usbON || !len) return FALSE; while(len){ + IWDG->KR = IWDG_REFRESH; int a = RB_write((ringbuffer*)&rbout, buf, len); - len -= a; - buf += a; - if(bufisempty){ - bufisempty = 0; - send_next(); - } + if(a > 0){ + len -= a; + buf += a; + } else if (a < 0) continue; // do nothing if buffer is in reading state + if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN } - return 1; + return TRUE; } int USB_putbyte(uint8_t byte){ - if(!usbON) return 0; - while(0 == RB_write((ringbuffer*)&rbout, &byte, 1)){ - if(bufisempty){ - bufisempty = 0; - send_next(); - } + if(!usbON) return FALSE; + int l = 0; + while((l = RB_write((ringbuffer*)&rbout, &byte, 1)) != 1){ + IWDG->KR = IWDG_REFRESH; + if(l < 0) continue; } - return 1; + if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN + return TRUE; } int USB_sendstr(const char *string){ - if(!string || !usbON) return 0; + if(!string || !usbON) return FALSE; int len = 0; const char *b = string; while(*b++) ++len; - if(!len) return 0; + if(!len) return FALSE; return USB_send((const uint8_t*)string, len); } @@ -95,13 +100,14 @@ int USB_sendstr(const char *string){ * @return amount of received bytes (negative, if overfull happened) */ int USB_receive(uint8_t *buf, int len){ - int sz = RB_read((ringbuffer*)&rbin, buf, len); + chkin(); if(bufovrfl){ - RB_clearbuf((ringbuffer*)&rbin); - if(!sz) sz = -1; - else sz = -sz; + while(1 != RB_clearbuf((ringbuffer*)&rbin)) IWDG->KR = IWDG_REFRESH; bufovrfl = 0; + return -1; } + int sz = RB_read((ringbuffer*)&rbin, buf, len); + if(sz < 0) return 0; // buffer in writting state return sz; } @@ -112,15 +118,22 @@ int USB_receive(uint8_t *buf, int len){ * @return strlen or negative value indicating overflow (if so, string won't be ends with 0 and buffer should be cleared) */ int USB_receivestr(char *buf, int len){ - int l = RB_readto((ringbuffer*)&rbin, '\n', (uint8_t*)buf, len); - if(l == 0) return 0; - if(--l < 0 || bufovrfl) RB_clearbuf((ringbuffer*)&rbin); - else buf[l] = 0; // replace '\n' with strend + chkin(); if(bufovrfl){ - if(l > 0) l = -l; - else l = -1; + while(1 != RB_clearbuf((ringbuffer*)&rbin)) IWDG->KR = IWDG_REFRESH; bufovrfl = 0; + return -1; } + int l = RB_readto((ringbuffer*)&rbin, '\n', (uint8_t*)buf, len); + if(l < 1){ + if(rbin.length == RB_datalen((ringbuffer*)&rbin)){ // buffer is full but no '\n' found + while(1 != RB_clearbuf((ringbuffer*)&rbin)) IWDG->KR = IWDG_REFRESH; + return -1; + } + return 0; + } + if(l == 0) return 0; + buf[l-1] = 0; // replace '\n' with strend return l; } diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/usb.h b/F0:F030,F042,F072/usbcan_ringbuffer/usb.h index 14512f2..4583b9b 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/usb.h +++ b/F0:F030,F042,F072/usbcan_ringbuffer/usb.h @@ -1,6 +1,5 @@ /* - * This file is part of the usbcanrb project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +22,7 @@ // sizes of ringbuffers for outgoing and incoming data #define RBOUTSZ (512) -#define RBINSZ (512) +#define RBINSZ (256) #define newline() USB_putbyte('\n') #define USND(s) do{USB_sendstr(s); USB_putbyte('\n');}while(0) diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.c b/F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.c index 9ef42e8..aea5344 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.c +++ b/F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.c @@ -1,6 +1,5 @@ /* - * This file is part of the usbcanrb project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include #include "usb.h" #include "usb_lib.h" @@ -131,7 +129,7 @@ _USB_LANG_ID_(LD, LANG_US); _USB_STRING_(SD, u"0.0.1"); _USB_STRING_(MD, u"Prolific Technology Inc."); _USB_STRING_(PD, u"USB-Serial Controller"); -_USB_STRING_(ID, u"can-usb"); +_USB_STRING_(ID, u"USB-STM32"); static void const *StringDescriptor[iDESCR_AMOUNT] = { [iLANGUAGE_DESCR] = &LD, [iMANUFACTURER_DESCR] = &MD, @@ -266,15 +264,29 @@ static void transmit_Handler(){ // EP3IN send_next(); } +static uint8_t volatile rcvbuf[USB_RXBUFSZ]; +static uint8_t volatile rcvbuflen = 0; + +void chkin(){ + if(bufovrfl) return; + if(!rcvbuflen) return; + int w = RB_write((ringbuffer*)&rbin, (uint8_t*)rcvbuf, rcvbuflen); + if(w < 0) return; + if(w != rcvbuflen) bufovrfl = 1; + rcvbuflen = 0; + uint16_t status = KEEP_DTOG(USB->EPnR[2]); // don't change DTOG + USB->EPnR[2] = status ^ USB_EPnR_STAT_RX; +} + +// receiver reads data from local buffer and only then ACK'ed static void receive_Handler(){ // EP2OUT - uint8_t buf[USB_RXBUFSZ]; - uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]); - uint8_t sz = EP_Read(2, (uint8_t*)buf); - if(sz){ - if(RB_write((ringbuffer*)&rbin, buf, sz) != sz) bufovrfl = 1; + uint16_t status = KEEP_DTOG_STAT(USB->EPnR[2]); // don't change DTOG and NACK + if(rcvbuflen){ + bufovrfl = 1; // lost last data + rcvbuflen = 0; } - // keep stat_tx & set ACK rx, clear RX ctr - USB->EPnR[2] = (epstatus & ~USB_EPnR_CTR_RX) ^ USB_EPnR_STAT_RX; + rcvbuflen = EP_Read(2, (uint8_t*)rcvbuf); + USB->EPnR[2] = status & ~USB_EPnR_CTR_RX; } static inline void std_h2d_req(){ @@ -436,3 +448,103 @@ int EP_Read(uint8_t number, uint8_t *buf){ return sz; } + +static uint16_t lastaddr = LASTADDR_DEFAULT; +/** + * Endpoint initialisation + * @param number - EP num (0...7) + * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) + * @param txsz - transmission buffer size @ USB/CAN buffer + * @param rxsz - reception buffer size @ USB/CAN buffer + * @param uint16_t (*func)(ep_t *ep) - EP handler function + * @return 0 if all OK + */ +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ + if(number >= STM32ENDPOINTS) return 4; // out of configured amount + if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large + if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE/ACCESSZ) return 2; // out of btable + USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); + USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; + if(rxsz & 1 || rxsz > USB_BTABLE_SIZE) return 3; // wrong rx buffer size + uint16_t countrx = 0; + if(rxsz < 64) countrx = rxsz / 2; + else{ + if(rxsz & 0x1f) return 3; // should be multiple of 32 + countrx = 31 + rxsz / 32; + } + USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; + endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + endpoints[number].txbufsz = txsz; + lastaddr += txsz; + USB_BTABLE->EP[number].USB_COUNT_TX = 0; + USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; + endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + lastaddr += rxsz; + USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; + endpoints[number].func = func; + return 0; +} + +// standard IRQ handler +void USB_IRQ(){ + if(USB->ISTR & USB_ISTR_RESET){ + usbON = 0; + // Reinit registers + USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + // Endpoint 0 - CONTROL + // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! + lastaddr = LASTADDR_DEFAULT; + // clear address, leave only enable bit + USB->DADDR = USB_DADDR_EF; + if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ + return; + } + USB->ISTR = ~USB_ISTR_RESET; + } + if(USB->ISTR & USB_ISTR_CTR){ + // EP number + uint8_t n = USB->ISTR & USB_ISTR_EPID; + // copy status register + uint16_t epstatus = USB->EPnR[n]; + // copy received bytes amount + endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter + // check direction + if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) + if(n == 0){ // control endpoint + if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack + EP_Read(0, setupdatabuf); + // interrupt handler will be called later + }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf + EP_Read(0, ep0databuf); + } + } + } + // call EP handler + if(endpoints[n].func) endpoints[n].func(endpoints[n]); + } + if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep + usbON = 0; +#ifndef STM32F0 + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; +#else + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LPMODE; +#endif + USB->ISTR = ~USB_ISTR_SUSP; + } + if(USB->ISTR & USB_ISTR_WKUP){ // wakeup +#ifndef STM32F0 + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags +#else + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LPMODE); +#endif + USB->ISTR = ~USB_ISTR_WKUP; + } +} + +#if defined STM32F3 +void usb_lp_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F1 +void usb_lp_can_rx0_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F0 +void usb_isr() __attribute__ ((alias ("USB_IRQ"))); +#endif diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.h b/F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.h index 8bfe48a..ec26927 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.h +++ b/F0:F030,F042,F072/usbcan_ringbuffer/usb_lib.h @@ -1,6 +1,5 @@ /* - * This file is part of the usbcanrb project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once #include @@ -170,3 +168,5 @@ void linecoding_handler(usb_LineCoding *lc); void clstate_handler(uint16_t val); void break_handler(); void vendor_handler(config_pack_t *packet); +void chkin(); +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)()); diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/usbcan.bin b/F0:F030,F042,F072/usbcan_ringbuffer/usbcan.bin index f3cbb5876edbe08e928064c0e153c0803f56457a..3fe74fe9472b23833ed038fa18371c3773146cbd 100755 GIT binary patch delta 6907 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 delta 6758 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 - + EnvironmentId - {cf63021e-ef53-49b0-b03b-2f2570cdf3b6} + {7bd84e39-ca37-46d3-be9d-99ebea85bc0d} ProjectExplorer.Project.ActiveTarget @@ -39,21 +39,21 @@ 1 0 false - false + true false - 1 + 0 true true 0 8 true false - 2 + 1 true - true + false true *.md, *.MD, Makefile - true + false true true @@ -69,15 +69,17 @@ true true + false + 0 true true true Builtin.DefaultTidyAndClazy - 4 - false + 8 + true @@ -91,12 +93,12 @@ Desktop Desktop Desktop - {91347f2c-5221-46a7-80b1-0a054ca02f79} + {65a14f9e-e008-4c1b-89df-4eaa4774b6e3} 0 0 0 - /home/eddy/Docs/SAO/ELECTRONICS/STM32/F0-srcs/usbcan_ringbuffer + /Big/Data/00__Electronics/STM32/F0-nolib/usbcan_ringbuffer @@ -106,8 +108,8 @@ GenericProjectManager.GenericMakeStep 1 - Сборка - Сборка + Build + Build ProjectExplorer.BuildSteps.Build @@ -119,8 +121,8 @@ GenericProjectManager.GenericMakeStep 1 - Очистка - Очистка + Clean + Clean ProjectExplorer.BuildSteps.Clean 2 @@ -128,15 +130,15 @@ false - По умолчанию + Default GenericProjectManager.GenericBuildConfiguration 1 0 - Развёртывание - Развёртывание + Deploy + Deploy ProjectExplorer.BuildSteps.Deploy 1 @@ -148,7 +150,9 @@ true true + 0 true + 2 diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/usbhw.c b/F0:F030,F042,F072/usbcan_ringbuffer/usbhw.c index 345138c..4f061b7 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/usbhw.c +++ b/F0:F030,F042,F072/usbcan_ringbuffer/usbhw.c @@ -1,6 +1,5 @@ /* - * This file is part of the usbcanrb project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +14,22 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include "usb.h" #include "usb_lib.h" // here we suppose that all PIN settings done in hw_setup earlier void USB_setup(){ - RCC->APB1ENR |= RCC_APB1ENR_CRSEN | RCC_APB1ENR_USBEN; // enable CRS (hsi48 sync) & USB +#if defined STM32F3 + NVIC_DisableIRQ(USB_LP_IRQn); + // remap USB LP & Wakeup interrupts to 75 and 76 - works only on pure F303 + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // enable tacting of SYSCFG + SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP; +#elif defined STM32F1 + NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); + NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); +#elif defined STM32F0 + NVIC_DisableIRQ(USB_IRQn); + RCC->APB1ENR |= RCC_APB1ENR_CRSEN; RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48 uint32_t tmout = 16000000; @@ -32,96 +40,24 @@ void USB_setup(){ CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only RCC->CFGR |= RCC_CFGR_SW; - // allow RESET and WKUPM interrupts - USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; - // clear flags - USB->ISTR = 0; - // and activate pullup +#endif + RCC->APB1ENR |= RCC_APB1ENR_USBEN; + //?? + USB->CNTR = USB_CNTR_FRES; // Force USB Reset + for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms + USB->CNTR = 0; + USB->BTABLE = 0; + USB->DADDR = 0; + USB->ISTR = 0; + USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts +#if defined STM32F3 + NVIC_EnableIRQ(USB_LP_IRQn); +#elif defined STM32F1 + NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); +#elif defined STM32F0 USB->BCDR |= USB_BCDR_DPPU; NVIC_EnableIRQ(USB_IRQn); +#endif } -static uint16_t lastaddr = LASTADDR_DEFAULT; -/** - * Endpoint initialisation - * @param number - EP num (0...7) - * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) - * @param txsz - transmission buffer size @ USB/CAN buffer - * @param rxsz - reception buffer size @ USB/CAN buffer - * @param uint16_t (*func)(ep_t *ep) - EP handler function - * @return 0 if all OK - */ -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ - if(number >= STM32ENDPOINTS) return 4; // out of configured amount - if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large - if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable - USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); - USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; - if(rxsz & 1 || rxsz > 512) return 3; // wrong rx buffer size - uint16_t countrx = 0; - if(rxsz < 64) countrx = rxsz / 2; - else{ - if(rxsz & 0x1f) return 3; // should be multiple of 32 - countrx = 31 + rxsz / 32; - } - USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; - endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); - endpoints[number].txbufsz = txsz; - lastaddr += txsz; - USB_BTABLE->EP[number].USB_COUNT_TX = 0; - USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; - endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); - lastaddr += rxsz; - USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; - endpoints[number].func = func; - return 0; -} - -// standard IRQ handler (just rename it due to MCU model) -void usb_isr(){ - if(USB->ISTR & USB_ISTR_RESET){ - usbON = 0; - // Reinit registers - USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; - // Endpoint 0 - CONTROL - // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! - lastaddr = LASTADDR_DEFAULT; - // clear address, leave only enable bit - USB->DADDR = USB_DADDR_EF; - if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ - return; - } - USB->ISTR = ~USB_ISTR_RESET; - } - if(USB->ISTR & USB_ISTR_CTR){ - // EP number - uint8_t n = USB->ISTR & USB_ISTR_EPID; - // copy status register - uint16_t epstatus = USB->EPnR[n]; - // copy received bytes amount - endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter - // check direction - if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) - if(n == 0){ // control endpoint - if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack - EP_Read(0, setupdatabuf); - // interrupt handler will be called later - }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf - EP_Read(0, ep0databuf); - } - } - } - // call EP handler - if(endpoints[n].func) endpoints[n].func(endpoints[n]); - } - if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep - usbON = 0; - USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LPMODE; - USB->ISTR = ~USB_ISTR_SUSP; - } - if(USB->ISTR & USB_ISTR_WKUP){ // wakeup - USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LPMODE); // clear suspend flags - USB->ISTR = ~USB_ISTR_WKUP; - } -} diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/usbhw.h b/F0:F030,F042,F072/usbcan_ringbuffer/usbhw.h index 14d40d1..1ca0482 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/usbhw.h +++ b/F0:F030,F042,F072/usbcan_ringbuffer/usbhw.h @@ -1,6 +1,5 @@ /* - * This file is part of the usbcanrb project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,17 +14,61 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once +#if defined STM32F0 #include +#elif defined STM32F1 +#include +// there's no this define in standard header +#define USB_BASE ((uint32_t)0x40005C00) +#elif defined STM32F3 +#include +#endif // max endpoints number #define STM32ENDPOINTS 8 /** * Buffers size definition **/ + +// F0 - USB2_16; F1 - USB1_16; F3 - 1/2 depending on series +#if !defined USB1_16 && !defined USB2_16 +#if defined STM32F0 +#define USB2_16 +#elif defined STM32F1 +#define USB1_16 +#else +#error "Can't determine USB1_16 or USB2_16, define by hands" +#endif +#endif + +// BTABLE_SIZE FOR STM32F3: +// In STM32F303/302xB/C, 512 bytes SRAM is not shared with CAN. +// In STM32F302x6/x8 and STM32F30xxD/E, 726 bytes dedicated SRAM and 256 bytes shared SRAM with CAN i.e. +// 1Kbytes dedicated SRAM in case CAN is disabled. +// remember, that USB_BTABLE_SIZE will be divided by ACCESSZ, so don't divide it twice for 32-bit addressing + +#ifdef NOCAN +#if defined STM32F0 +#define USB_BTABLE_SIZE 1024 +#elif defined STM32F3 +#define USB_BTABLE_SIZE 512 +#warning "Please, check real buffer size due to docs" +#else +#error "define STM32F0 or STM32F3" +#endif +#else // !NOCAN: F0/F3 with CAN or F1 (can't simultaneously run CAN and USB) +#if defined STM32F0 #define USB_BTABLE_SIZE 768 +#elif defined STM32F3 +#define USB_BTABLE_SIZE 512 +#warning "Please, check real buffer size due to docs" +#else // STM32F103: 1024 bytes but with 32-bit addressing +#define USB_BTABLE_SIZE 1024 +#endif +#endif // NOCAN + // first 64 bytes of USB_BTABLE are registers! //#define USB_EP0_BASEADDR 64 // for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303) @@ -81,8 +124,10 @@ typedef struct { __IO uint32_t FNR; __IO uint32_t DADDR; __IO uint32_t BTABLE; +#ifdef STM32F0 __IO uint32_t LPMCSR; __IO uint32_t BCDR; +#endif } USB_TypeDef; // F303 D/E have 2x16 access scheme @@ -112,4 +157,3 @@ typedef struct{ } USB_BtableDef; void USB_setup(); -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)()); diff --git a/F0:F030,F042,F072/usbcan_ringbuffer/version.inc b/F0:F030,F042,F072/usbcan_ringbuffer/version.inc index a7bef25..cf20f39 100644 --- a/F0:F030,F042,F072/usbcan_ringbuffer/version.inc +++ b/F0:F030,F042,F072/usbcan_ringbuffer/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "35" -#define BUILD_DATE "2024-07-02" +#define BUILD_NUMBER "49" +#define BUILD_DATE "2024-09-02" diff --git a/F1:F103/PL2303_rb_strip/Makefile b/F1:F103/PL2303_rb_strip/Makefile new file mode 100644 index 0000000..09f28fd --- /dev/null +++ b/F1:F103/PL2303_rb_strip/Makefile @@ -0,0 +1,10 @@ +BINARY := PL2303 +# MCU code +MCU ?= F103x6 +# change this linking script depending on particular MCU model, +LDSCRIPT ?= stm32f103x6.ld +#DEFINES := -DUSB1_16 -DSTM32F10X_LD +DEFINES := -DSTM32F10X_LD + +include ../makefile.f1 +include ../../makefile.stm32 diff --git a/F1:F103/PL2303_rb_strip/PL2303.bin b/F1:F103/PL2303_rb_strip/PL2303.bin new file mode 100755 index 0000000000000000000000000000000000000000..48c0a495f42d76f5a033b91a3bf488d77b0bc152 GIT binary patch literal 5476 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. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "hardware.h" + +static inline void gpio_setup(){ + // Enable clocks to the GPIO subsystems, turn on AFIO clocking to disable SWD/JTAG + RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN; + // turn off SWJ/JTAG +// AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE; + AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // for PA15 + // Set led as opendrain output + GPIOC->CRH |= CRH(13, CNF_ODOUTPUT | MODE_SLOW); + // USB pullup (PA15) - pushpull output + GPIOA->CRH = /* CRH(8, CNF_PPOUTPUT | MODE_SLOW) | */ CRH(15, CNF_PPOUTPUT | MODE_SLOW); +} + +void hw_setup(){ + gpio_setup(); +} + diff --git a/F1:F103/PL2303_rb_strip/hardware.h b/F1:F103/PL2303_rb_strip/hardware.h new file mode 100644 index 0000000..107e451 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/hardware.h @@ -0,0 +1,40 @@ +/* + * This file is part of the pl2303 project. + * Copyright 2022 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +// LED0 - PC13 (bluepill), blinking each second +// PA8 - my board +#define LED0_port GPIOC +#define LED0_pin (1<<13) + +#define LED_blink(x) pin_toggle(x ## _port, x ## _pin) +#define LED_on(x) pin_clear(x ## _port, x ## _pin) +#define LED_off(x) pin_set(x ## _port, x ## _pin) + +#define USBPU_port GPIOA +#define USBPU_pin (1<<15) +#define USBPU_ON() pin_set(USBPU_port, USBPU_pin) +#define USBPU_OFF() pin_clear(USBPU_port, USBPU_pin) + +extern volatile uint32_t Tms; + +void hw_setup(); + diff --git a/F1:F103/PL2303_rb_strip/main.c b/F1:F103/PL2303_rb_strip/main.c new file mode 100644 index 0000000..d44a721 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/main.c @@ -0,0 +1,54 @@ +/* + * This file is part of the pl2303 project. + * Copyright 2024 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "hardware.h" +#include "proto.h" +#include "usb.h" + +#define MAXSTRLEN RBINSZ + +volatile uint32_t Tms = 0; + +void sys_tick_handler(void){ + ++Tms; +} + +int main(void){ + char inbuff[MAXSTRLEN+1]; + StartHSE(); + hw_setup(); + USBPU_OFF(); + SysTick_Config(72000); + USB_setup(); + USBPU_ON(); + + uint32_t ctr = Tms; + while(1){ + if(Tms - ctr > 499){ + ctr = Tms; + LED_blink(LED0); + } + int l = USB_receivestr(inbuff, MAXSTRLEN); + if(l < 0) USB_sendstr("ERROR: USB buffer overflow or string was too long\n"); + else if(l){ + USB_sendstr("RECEIVED: _"); USB_sendstr(inbuff); USB_sendstr("_\n"); + const char *ans = parse_cmd(inbuff); + if(ans) USB_sendstr(ans); + } + } +} diff --git a/F1:F103/PL2303_rb_strip/openocd.cfg b/F1:F103/PL2303_rb_strip/openocd.cfg new file mode 100644 index 0000000..18ecde1 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/openocd.cfg @@ -0,0 +1,4 @@ +set FLASH_SIZE 0x20000 + +source [find interface/stlink-v2-1.cfg] +source [find target/stm32f1x.cfg] diff --git a/F1:F103/PL2303_rb_strip/pl2303.cflags b/F1:F103/PL2303_rb_strip/pl2303.cflags new file mode 100644 index 0000000..68d5165 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/pl2303.cflags @@ -0,0 +1 @@ +-std=c17 \ No newline at end of file diff --git a/F1:F103/PL2303_rb_strip/pl2303.config b/F1:F103/PL2303_rb_strip/pl2303.config new file mode 100644 index 0000000..c41f0d7 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/pl2303.config @@ -0,0 +1,6 @@ +// Add predefined macros for your project here. For example: +// #define THE_ANSWER 42 +#define EBUG +#define STM32F1 +#define STM32F103x8 +#define STM32F10X_MD diff --git a/F1:F103/PL2303_rb_strip/pl2303.creator b/F1:F103/PL2303_rb_strip/pl2303.creator new file mode 100644 index 0000000..e94cbbd --- /dev/null +++ b/F1:F103/PL2303_rb_strip/pl2303.creator @@ -0,0 +1 @@ +[General] diff --git a/F1:F103/PL2303_rb_strip/pl2303.creator.user b/F1:F103/PL2303_rb_strip/pl2303.creator.user new file mode 100644 index 0000000..e185775 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/pl2303.creator.user @@ -0,0 +1,181 @@ + + + + + + EnvironmentId + {7bd84e39-ca37-46d3-be9d-99ebea85bc0d} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + KOI8-R + false + 4 + false + 80 + true + true + 1 + 0 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + false + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + false + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 8 + false + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Desktop + {65a14f9e-e008-4c1b-89df-4eaa4774b6e3} + 0 + 0 + 0 + + /Big/Data/00__Electronics/STM32/F303-nolib/blink + + + + all + + true + GenericProjectManager.GenericMakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + GenericProjectManager.GenericMakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Default + GenericProjectManager.GenericBuildConfiguration + + 1 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/F1:F103/PL2303_rb_strip/pl2303.cxxflags b/F1:F103/PL2303_rb_strip/pl2303.cxxflags new file mode 100644 index 0000000..6435dfc --- /dev/null +++ b/F1:F103/PL2303_rb_strip/pl2303.cxxflags @@ -0,0 +1 @@ +-std=c++17 \ No newline at end of file diff --git a/F1:F103/PL2303_rb_strip/pl2303.files b/F1:F103/PL2303_rb_strip/pl2303.files new file mode 100644 index 0000000..e7206a9 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/pl2303.files @@ -0,0 +1,13 @@ +hardware.c +hardware.h +main.c +proto.c +proto.h +ringbuffer.c +ringbuffer.h +usb.c +usb.h +usb_lib.c +usb_lib.h +usbhw.c +usbhw.h diff --git a/F1:F103/PL2303_rb_strip/pl2303.includes b/F1:F103/PL2303_rb_strip/pl2303.includes new file mode 100644 index 0000000..06d1130 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/pl2303.includes @@ -0,0 +1,6 @@ +. +../inc +../inc/Fx +../inc/cm +../inc/ld +../inc/startup diff --git a/F1:F103/PL2303_rb_strip/proto.c b/F1:F103/PL2303_rb_strip/proto.c new file mode 100644 index 0000000..31b4655 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/proto.c @@ -0,0 +1,263 @@ +/* + * This file is part of the pl2303 project. + * Copyright 2022 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "proto.h" +#include "hardware.h" +#include "usb.h" + +const char *test = "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789S123456789T123456789U123456789V123456789W123456789X123456789Y"; + +char *omit_spaces(const char *buf){ + while(*buf){ + if(*buf > ' ') break; + ++buf; + } + return (char*)buf; +} + +// In case of overflow return `buf` and N==0xffffffff +// read decimal number & return pointer to next non-number symbol +static char *getdec(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '9'){ + break; + } + if(num > 429496729 || (num == 429496729 && c > '5')){ // overflow + *N = 0xffffff; + return start; + } + num *= 10; + num += c - '0'; + ++buf; + } + *N = num; + return (char*)buf; +} +// read hexadecimal number (without 0x prefix!) +static char *gethex(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + uint8_t M = 0; + if(c >= '0' && c <= '9'){ + M = '0'; + }else if(c >= 'A' && c <= 'F'){ + M = 'A' - 10; + }else if(c >= 'a' && c <= 'f'){ + M = 'a' - 10; + } + if(M){ + if(num & 0xf0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 4; + num += c - M; + }else{ + break; + } + ++buf; + } + *N = num; + return (char*)buf; +} +// read octal number (without 0 prefix!) +static char *getoct(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '7'){ + break; + } + if(num & 0xe0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 3; + num += c - '0'; + ++buf; + } + *N = num; + return (char*)buf; +} +// read binary number (without b prefix!) +static char *getbin(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '1'){ + break; + } + if(num & 0x80000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 1; + if(c == '1') num |= 1; + ++buf; + } + *N = num; + return (char*)buf; +} + +/** + * @brief getnum - read uint32_t from string (dec, hex or bin: 127, 0x7f, 0b1111111) + * @param buf - buffer with number and so on + * @param N - the number read + * @return pointer to first non-number symbol in buf + * (if it is == buf, there's no number or if *N==0xffffffff there was overflow) + */ +char *getnum(const char *txt, uint32_t *N){ + char *nxt = NULL; + char *s = omit_spaces(txt); + if(*s == '0'){ // hex, oct or 0 + if(s[1] == 'x' || s[1] == 'X'){ // hex + nxt = gethex(s+2, N); + if(nxt == s+2) nxt = (char*)txt; + }else if(s[1] > '0'-1 && s[1] < '8'){ // oct + nxt = getoct(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ // 0 + nxt = s+1; + *N = 0; + } + }else if(*s == 'b' || *s == 'B'){ + nxt = getbin(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ + nxt = getdec(s, N); + if(nxt == s) nxt = (char*)txt; + } + return nxt; +} + +const char* helpmsg = + "'i' - print USB->ISTR state\n" + "'p' - toggle USB pullup\n" + "'N' - read number (dec, 0xhex, 0oct, bbin) and show it in decimal\n" + "'R' - software reset\n" + "'T' - test usb sending a very large message\n" + "'U' - get USB status\n" +; + +extern uint8_t usbON; +const char *parse_cmd(const char *buf){ + uint32_t u3; + if(buf[1] == '\n' || !buf[1]){ // one symbol commands + switch(*buf){ + case 'i': + USB_sendstr("USB->ISTR="); + USB_sendstr(u2hexstr(USB->ISTR)); + USB_sendstr(", USB->CNTR="); + USB_sendstr(u2hexstr(USB->CNTR)); + newline(); + break; + case 'p': + pin_toggle(USBPU_port, USBPU_pin); + USB_sendstr("USB pullup is "); + if(pin_read(USBPU_port, USBPU_pin)) USB_sendstr("off\n"); + else USB_sendstr("on\n"); + break; + case 'R': + USB_sendstr("Soft reset\n"); + USB_sendall(); + NVIC_SystemReset(); + break; + case 'T': + u3 = Tms; + for(int i = 0; i < 1000; ++i) USB_sendstr(test); + USB_sendstr("\n\nspd="); + USB_sendstr(u2str(2000000000/(Tms - u3))); newline(); // strlen == 2Mbit, speed in bits per second + break; + case 'U': + USB_sendstr("USB status: "); + if(usbON) USB_sendstr("ON"); + else USB_sendstr("OFF"); + newline(); + break; + default: + return helpmsg; + } + return NULL; + } + uint32_t Num = 0; + char *nxt; + switch(*buf){ // long messages + case 'N': + ++buf; + nxt = getnum(buf, &Num); + if(buf == nxt){ + if(Num == 0) return "Wrong number\n"; + return "Integer32 overflow\n"; + } + USB_sendstr("You give: "); + USB_sendstr(u2str(Num)); + if(*nxt && *nxt != '\n'){ + USB_sendstr(", the rest of string: "); + USB_sendstr(nxt); + }else newline(); + break; + default: + return buf; + } + return NULL; +} + + +// return string with number `val` +char *u2str(uint32_t val){ + static char strbuf[11]; + char *bufptr = &strbuf[10]; + *bufptr = 0; + if(!val){ + *(--bufptr) = '0'; + }else{ + while(val){ + *(--bufptr) = val % 10 + '0'; + val /= 10; + } + } + return bufptr; +} + +char *u2hexstr(uint32_t val){ + static char strbuf[11] = "0x"; + char *sptr = strbuf + 2; + uint8_t *ptr = (uint8_t*)&val + 3; + int8_t i, j, z=1; + for(i = 0; i < 4; ++i, --ptr){ + if(*ptr == 0){ // omit leading zeros + if(i == 3) z = 0; + if(z) continue; + } + else z = 0; + for(j = 1; j > -1; --j){ + uint8_t half = (*ptr >> (4*j)) & 0x0f; + if(half < 10) *sptr++ = half + '0'; + else *sptr++ = half - 10 + 'a'; + } + } + *sptr = 0; + return strbuf; +} diff --git a/F1:F103/PL2303_rb_strip/proto.h b/F1:F103/PL2303_rb_strip/proto.h new file mode 100644 index 0000000..e4ecd05 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/proto.h @@ -0,0 +1,31 @@ +/* + * This file is part of the pl2303 project. + * Copyright 2022 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#ifndef PROTO_H__ +#define PROTO_H__ + +#include + +const char *parse_cmd(const char *buf); +char *omit_spaces(const char *buf); +char *getnum(const char *buf, uint32_t *N); +char *u2str(uint32_t val); +char *u2hexstr(uint32_t val); + +#endif // PROTO_H__ diff --git a/F1:F103/PL2303_rb_strip/ringbuffer.c b/F1:F103/PL2303_rb_strip/ringbuffer.c new file mode 100644 index 0000000..8d8d6ca --- /dev/null +++ b/F1:F103/PL2303_rb_strip/ringbuffer.c @@ -0,0 +1,167 @@ +/* + * Copyright 2023 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ringbuffer.h" + +static int datalen(ringbuffer *b){ + if(b->tail >= b->head) return (b->tail - b->head); + else return (b->length - b->head + b->tail); +} + +// stored data length +int RB_datalen(ringbuffer *b){ + if(b->busy) return -1; + b->busy = 1; + int l = datalen(b); + b->busy = 0; + return l; +} + +static int hasbyte(ringbuffer *b, uint8_t byte){ + if(b->head == b->tail) return -1; // no data in buffer + int startidx = b->head; + if(b->head > b->tail){ // + for(int found = b->head; found < b->length; ++found) + if(b->data[found] == byte) return found; + startidx = 0; + } + for(int found = startidx; found < b->tail; ++found) + if(b->data[found] == byte) return found; + return -1; +} + +/** + * @brief RB_hasbyte - check if buffer has given byte stored + * @param b - buffer + * @param byte - byte to find + * @return index if found, -1 if none or busy + */ +int RB_hasbyte(ringbuffer *b, uint8_t byte){ + if(b->busy) return -1; + b->busy = 1; + int ret = hasbyte(b, byte); + b->busy = 0; + return ret; +} + +// poor memcpy +static void mcpy(uint8_t *targ, const uint8_t *src, int l){ + while(l--) *targ++ = *src++; +} + +// increment head or tail +TRUE_INLINE void incr(ringbuffer *b, volatile int *what, int n){ + *what += n; + if(*what >= b->length) *what -= b->length; +} + +static int read(ringbuffer *b, uint8_t *s, int len){ + int l = datalen(b); + if(!l) return 0; + if(l > len) l = len; + int _1st = b->length - b->head; + if(_1st > l) _1st = l; + if(_1st > len) _1st = len; + mcpy(s, b->data + b->head, _1st); + if(_1st < len && l > _1st){ + mcpy(s+_1st, b->data, l - _1st); + incr(b, &b->head, l); + return l; + } + incr(b, &b->head, _1st); + return _1st; +} + +/** + * @brief RB_read - read data from ringbuffer + * @param b - buffer + * @param s - array to write data + * @param len - max len of `s` + * @return bytes read or -1 if busy + */ +int RB_read(ringbuffer *b, uint8_t *s, int len){ + if(b->busy) return -1; + b->busy = 1; + int r = read(b, s, len); + b->busy = 0; + return r; +} + +static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){ + int idx = hasbyte(b, byte); + if(idx < 0) return 0; + int partlen = idx + 1 - b->head; + // now calculate length of new data portion + if(idx < b->head) partlen += b->length; + if(partlen > len) return -read(b, s, len); + return read(b, s, partlen); +} + +/** + * @brief RB_readto fill array `s` with data until byte `byte` (with it) + * @param b - ringbuffer + * @param byte - check byte + * @param s - buffer to write data + * @param len - length of `s` + * @return amount of bytes written (negative, if lenbusy) return -1; + b->busy = 1; + int n = readto(b, byte, s, len); + b->busy = 0; + return n; +} + +static int write(ringbuffer *b, const uint8_t *str, int l){ + int r = b->length - 1 - datalen(b); // rest length + if(l > r) l = r; + if(!l) return 0; + int _1st = b->length - b->tail; + if(_1st > l) _1st = l; + mcpy(b->data + b->tail, str, _1st); + if(_1st < l){ // add another piece from start + mcpy(b->data, str+_1st, l-_1st); + } + incr(b, &b->tail, l); + return l; +} + +/** + * @brief RB_write - write some data to ringbuffer + * @param b - buffer + * @param str - data + * @param l - length + * @return amount of bytes written or -1 if busy + */ +int RB_write(ringbuffer *b, const uint8_t *str, int l){ + if(b->busy) return -1; + b->busy = 1; + int w = write(b, str, l); + b->busy = 0; + return w; +} + +// just delete all information in buffer `b` +int RB_clearbuf(ringbuffer *b){ + if(b->busy) return -1; + b->busy = 1; + b->head = 0; + b->tail = 0; + b->busy = 0; + return 1; +} diff --git a/F1:F103/PL2303_rb_strip/ringbuffer.h b/F1:F103/PL2303_rb_strip/ringbuffer.h new file mode 100644 index 0000000..ed2cf95 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/ringbuffer.h @@ -0,0 +1,41 @@ +/* + * Copyright 2023 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#if defined STM32F0 +#include +#elif defined STM32F1 +#include +#elif defined STM32F3 +#include +#endif + +typedef struct{ + uint8_t *data; // data buffer + const int length; // its length + int head; // head index + int tail; // tail index + volatile int busy; // == TRUE if buffer is busy now +} ringbuffer; + +int RB_read(ringbuffer *b, uint8_t *s, int len); +int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len); +int RB_hasbyte(ringbuffer *b, uint8_t byte); +int RB_write(ringbuffer *b, const uint8_t *str, int l); +int RB_datalen(ringbuffer *b); +int RB_clearbuf(ringbuffer *b); diff --git a/F1:F103/PL2303_rb_strip/usb.c b/F1:F103/PL2303_rb_strip/usb.c new file mode 100644 index 0000000..a2ee479 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/usb.c @@ -0,0 +1,135 @@ +/* + * Copyright 2024 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "hardware.h" +#include "usb.h" +#include "usb_lib.h" + +static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data +// ring buffers for incoming and outgoing data +static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ]; +volatile ringbuffer rbout = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0}; +volatile ringbuffer rbin = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0}; +// inbuf overflow when receiving +volatile uint8_t bufovrfl = 0; +// last send data size +static volatile int lastdsz = 0; + +// called from transmit EP +void send_next(){ + int buflen = RB_read((ringbuffer*)&rbout, (uint8_t*)usbbuff, USB_TXBUFSZ); + if(buflen == 0){ + if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send + lastdsz = 0; + return; + }else if(buflen < 0){ + lastdsz = 0; + // Uncomment next line if you want 4Mbit/s instead of 6Mbit/s + //EP_Write(3, NULL, 0); // send ZLP if buffer is in writting state now + return; + } + EP_Write(3, (uint8_t*)usbbuff, buflen); + lastdsz = buflen; +} + +// blocking send full content of ring buffer +int USB_sendall(){ + while(lastdsz > 0){ + if(!usbON) return FALSE; + } + return TRUE; +} + +// put `buf` into queue to send +int USB_send(const uint8_t *buf, int len){ + if(!buf || !usbON || !len) return FALSE; + while(len){ + int a = RB_write((ringbuffer*)&rbout, buf, len); + if(a > 0){ + len -= a; + buf += a; + } else if (a < 0) continue; // do nothing if buffer is in reading state + if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN + } + return TRUE; +} + +int USB_putbyte(uint8_t byte){ + if(!usbON) return FALSE; + int l = 0; + while((l = RB_write((ringbuffer*)&rbout, &byte, 1)) != 1){ + if(l < 0) continue; + } + if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN + return TRUE; +} + +int USB_sendstr(const char *string){ + if(!string || !usbON) return FALSE; + int len = 0; + const char *b = string; + while(*b++) ++len; + if(!len) return FALSE; + return USB_send((const uint8_t*)string, len); +} + +/** + * @brief USB_receive - get binary data from receiving ring-buffer + * @param buf (i) - buffer for received data + * @param len - length of `buf` + * @return amount of received bytes (negative, if overfull happened) + */ +int USB_receive(uint8_t *buf, int len){ + chkin(); + if(bufovrfl){ + while(1 != RB_clearbuf((ringbuffer*)&rbin)); + bufovrfl = 0; + return -1; + } + int sz = RB_read((ringbuffer*)&rbin, buf, len); + if(sz < 0) return 0; // buffer in writting state + return sz; +} + +/** + * @brief USB_receivestr - get string up to '\n' and replace '\n' with 0 + * @param buf - receiving buffer + * @param len - its length + * @return strlen or negative value indicating overflow (if so, string won't be ends with 0 and buffer should be cleared) + */ +int USB_receivestr(char *buf, int len){ + chkin(); + if(bufovrfl){ + while(1 != RB_clearbuf((ringbuffer*)&rbin)); + bufovrfl = 0; + return -1; + } + int l = RB_readto((ringbuffer*)&rbin, '\n', (uint8_t*)buf, len); + if(l < 1){ + if(rbin.length == RB_datalen((ringbuffer*)&rbin)){ // buffer is full but no '\n' found + while(1 != RB_clearbuf((ringbuffer*)&rbin)); + return -1; + } + return 0; + } + if(l == 0) return 0; + buf[l-1] = 0; // replace '\n' with strend + return l; +} + diff --git a/F1:F103/PL2303_rb_strip/usb.h b/F1:F103/PL2303_rb_strip/usb.h new file mode 100644 index 0000000..2416d62 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/usb.h @@ -0,0 +1,48 @@ +/* + * Copyright 2024 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "ringbuffer.h" +#include "usbhw.h" + +// sizes of ringbuffers for outgoing and incoming data +#define RBOUTSZ (2048) +#define RBINSZ (2048) + +#define newline() USB_putbyte('\n') +#define USND(s) do{USB_sendstr(s); USB_putbyte('\n');}while(0) + +#define STR_HELPER(s) #s +#define STR(s) STR_HELPER(s) + +#ifdef EBUG +#define DBG(str) do{USB_sendstr(__FILE__ " (L" STR(__LINE__) "): " str); newline();}while(0) +#else +#define DBG(str) +#endif + +extern volatile ringbuffer rbout, rbin; +extern volatile uint8_t bufisempty, bufovrfl; + +void send_next(); +int USB_sendall(); +int USB_send(const uint8_t *buf, int len); +int USB_putbyte(uint8_t byte); +int USB_sendstr(const char *string); +int USB_receive(uint8_t *buf, int len); +int USB_receivestr(char *buf, int len); diff --git a/F1:F103/PL2303_rb_strip/usb_lib.c b/F1:F103/PL2303_rb_strip/usb_lib.c new file mode 100644 index 0000000..aea5344 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/usb_lib.c @@ -0,0 +1,550 @@ +/* + * Copyright 2024 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "usb.h" +#include "usb_lib.h" +#include "usbhw.h" + +ep_t endpoints[STM32ENDPOINTS]; + +static uint16_t USB_Addr = 0; +static usb_LineCoding lineCoding = {115200, 0, 0, 8}; +uint8_t ep0databuf[EP0DATABUF_SIZE], setupdatabuf[EP0DATABUF_SIZE]; +config_pack_t *setup_packet = (config_pack_t*) setupdatabuf; + +usb_LineCoding getLineCoding(){return lineCoding;} + +volatile uint8_t usbON = 0; // device disconnected from terminal + +// definition of parts common for USB_DeviceDescriptor & USB_DeviceQualifierDescriptor +#define bcdUSB_L 0x10 +#define bcdUSB_H 0x01 +#define bDeviceClass 0 +#define bDeviceSubClass 0 +#define bDeviceProtocol 0 +#define bNumConfigurations 1 + +static const uint8_t USB_DeviceDescriptor[] = { + 18, // bLength + 0x01, // bDescriptorType - Device descriptor + bcdUSB_L, // bcdUSB_L - 1.10 + bcdUSB_H, // bcdUSB_H + bDeviceClass, // bDeviceClass - USB_COMM + bDeviceSubClass, // bDeviceSubClass + bDeviceProtocol, // bDeviceProtocol + USB_EP0_BUFSZ, // bMaxPacketSize + 0x7b, // idVendor_L PL2303: VID=0x067b, PID=0x2303 + 0x06, // idVendor_H + 0x03, // idProduct_L + 0x23, // idProduct_H + 0x00, // bcdDevice_Ver_L + 0x03, // bcdDevice_Ver_H + iMANUFACTURER_DESCR, // iManufacturer + iPRODUCT_DESCR, // iProduct + iSERIAL_DESCR, // iSerialNumber + bNumConfigurations // bNumConfigurations +}; + +static const uint8_t USB_DeviceQualifierDescriptor[] = { + 10, //bLength + 0x06, // bDescriptorType - Device qualifier + bcdUSB_L, // bcdUSB_L + bcdUSB_H, // bcdUSB_H + bDeviceClass, // bDeviceClass + bDeviceSubClass, // bDeviceSubClass + bDeviceProtocol, // bDeviceProtocol + USB_EP0_BUFSZ, // bMaxPacketSize0 + bNumConfigurations, // bNumConfigurations + 0x00 // Reserved +}; + +static const uint8_t USB_ConfigDescriptor[] = { + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + 0x02, /* bDescriptorType: Configuration */ + 39, /* wTotalLength:no of returned bytes */ + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xa0, /* bmAttributes - Bus powered, Remote wakeup */ + 0x32, /* MaxPower 100 mA */ + + /*---------------------------------------------------------------------------*/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: Interface */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x03, /* bNumEndpoints: 3 endpoints used */ + 0xff, /* bInterfaceClass */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + iINTERFACE_DESCR, /* iInterface: */ +/////////////////////////////////////////////////// + /*Endpoint 1 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + 0x05, /* bDescriptorType: Endpoint */ + 0x81, /* bEndpointAddress IN1 */ + 0x03, /* bmAttributes: Interrupt */ + 0x0a, /* wMaxPacketSize LO: */ + 0x00, /* wMaxPacketSize HI: */ + 0x01, /* bInterval: */ + + /*Endpoint OUT2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + 0x05, /* bDescriptorType: Endpoint */ + 0x02, /* bEndpointAddress: OUT2 */ + 0x02, /* bmAttributes: Bulk */ + (USB_RXBUFSZ & 0xff), /* wMaxPacketSize: 64 */ + (USB_RXBUFSZ >> 8), + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN3 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + 0x05, /* bDescriptorType: Endpoint */ + 0x83, /* bEndpointAddress IN3 */ + 0x02, /* bmAttributes: Bulk */ + (USB_TXBUFSZ & 0xff), /* wMaxPacketSize: 64 */ + (USB_TXBUFSZ >> 8), + 0x00, /* bInterval: ignore for Bulk transfer */ +}; + +_USB_LANG_ID_(LD, LANG_US); +_USB_STRING_(SD, u"0.0.1"); +_USB_STRING_(MD, u"Prolific Technology Inc."); +_USB_STRING_(PD, u"USB-Serial Controller"); +_USB_STRING_(ID, u"USB-STM32"); +static void const *StringDescriptor[iDESCR_AMOUNT] = { + [iLANGUAGE_DESCR] = &LD, + [iMANUFACTURER_DESCR] = &MD, + [iPRODUCT_DESCR] = &PD, + [iSERIAL_DESCR] = &SD, + [iINTERFACE_DESCR] = &ID +}; + + +/* + * default handlers + */ +// SET_LINE_CODING +void WEAK linecoding_handler(usb_LineCoding __attribute__((unused)) *lc){ +} + +// SET_CONTROL_LINE_STATE +void WEAK clstate_handler(uint16_t __attribute__((unused)) val){ +} + +// SEND_BREAK +void WEAK break_handler(){ +} + +// handler of vendor requests +void WEAK vendor_handler(config_pack_t *packet){ + uint16_t c; + if(packet->bmRequestType & 0x80){ // read + switch(packet->wValue){ + case 0x8484: + c = 2; + break; + case 0x0080: + c = 1; + break; + case 0x8686: + c = 0xaa; + break; + default: + c = 0; + } + EP_WriteIRQ(0, (uint8_t*)&c, 1); + }else{ // write ZLP + c = 0; + EP_WriteIRQ(0, (uint8_t *)&c, 0); + } +} + +static void wr0(const uint8_t *buf, uint16_t size){ + if(setup_packet->wLength < size) size = setup_packet->wLength; // shortened request + if(size < endpoints[0].txbufsz){ + EP_WriteIRQ(0, buf, size); + return; + } + while(size){ + uint16_t l = size; + if(l > endpoints[0].txbufsz) l = endpoints[0].txbufsz; + EP_WriteIRQ(0, buf, l); + buf += l; + size -= l; + uint8_t needzlp = (l == endpoints[0].txbufsz) ? 1 : 0; + if(size || needzlp){ // send last data buffer + uint16_t status = KEEP_DTOG(USB->EPnR[0]); + // keep DTOGs, clear CTR_RX,TX, set TX VALID, leave stat_Rx + USB->EPnR[0] = (status & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX|USB_EPnR_STAT_RX)) + ^ USB_EPnR_STAT_TX; + uint32_t ctr = 1000000; + while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0){IWDG->KR = IWDG_REFRESH;}; + if((USB->ISTR & USB_ISTR_CTR) == 0){ + return; + } + if(needzlp) EP_WriteIRQ(0, (uint8_t*)0, 0); + } + } +} + +static inline void get_descriptor(){ + uint8_t descrtype = setup_packet->wValue >> 8, + descridx = setup_packet->wValue & 0xff; + switch(descrtype){ + case DEVICE_DESCRIPTOR: + wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor)); + break; + case CONFIGURATION_DESCRIPTOR: + wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor)); + break; + case STRING_DESCRIPTOR: + if(descridx < iDESCR_AMOUNT) wr0((const uint8_t *)StringDescriptor[descridx], *((uint8_t*)StringDescriptor[descridx])); + else EP_WriteIRQ(0, (uint8_t*)0, 0); + break; + case DEVICE_QUALIFIER_DESCRIPTOR: + wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]); + break; + default: + break; + } +} + +static uint16_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured) +static inline void std_d2h_req(){ + uint16_t status = 0; // bus powered + switch(setup_packet->bRequest){ + case GET_DESCRIPTOR: + get_descriptor(); + break; + case GET_STATUS: + EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered + break; + case GET_CONFIGURATION: + EP_WriteIRQ(0, (uint8_t*)&configuration, 1); + break; + default: + break; + } +} + +// interrupt IN handler (never used?) +static void EP1_Handler(){ + uint16_t epstatus = KEEP_DTOG(USB->EPnR[1]); + if(RX_FLAG(epstatus)) epstatus = (epstatus & ~USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_RX; // set valid RX + else epstatus = epstatus & ~(USB_EPnR_STAT_TX|USB_EPnR_STAT_RX); + // clear CTR + epstatus = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX)); + USB->EPnR[1] = epstatus; +} + +// data IN/OUT handlers +static void transmit_Handler(){ // EP3IN + uint16_t epstatus = KEEP_DTOG_STAT(USB->EPnR[3]); + // clear CTR keep DTOGs & STATs + USB->EPnR[3] = (epstatus & ~(USB_EPnR_CTR_TX)); // clear TX ctr + send_next(); +} + +static uint8_t volatile rcvbuf[USB_RXBUFSZ]; +static uint8_t volatile rcvbuflen = 0; + +void chkin(){ + if(bufovrfl) return; + if(!rcvbuflen) return; + int w = RB_write((ringbuffer*)&rbin, (uint8_t*)rcvbuf, rcvbuflen); + if(w < 0) return; + if(w != rcvbuflen) bufovrfl = 1; + rcvbuflen = 0; + uint16_t status = KEEP_DTOG(USB->EPnR[2]); // don't change DTOG + USB->EPnR[2] = status ^ USB_EPnR_STAT_RX; +} + +// receiver reads data from local buffer and only then ACK'ed +static void receive_Handler(){ // EP2OUT + uint16_t status = KEEP_DTOG_STAT(USB->EPnR[2]); // don't change DTOG and NACK + if(rcvbuflen){ + bufovrfl = 1; // lost last data + rcvbuflen = 0; + } + rcvbuflen = EP_Read(2, (uint8_t*)rcvbuf); + USB->EPnR[2] = status & ~USB_EPnR_CTR_RX; +} + +static inline void std_h2d_req(){ + switch(setup_packet->bRequest){ + case SET_ADDRESS: + // new address will be assigned later - after acknowlegement or request to host + USB_Addr = setup_packet->wValue; + break; + case SET_CONFIGURATION: + // Now device configured + configuration = setup_packet->wValue; + EP_Init(1, EP_TYPE_INTERRUPT, USB_EP1BUFSZ, 0, EP1_Handler); // IN1 - transmit + EP_Init(2, EP_TYPE_BULK, 0, USB_RXBUFSZ, receive_Handler); // OUT2 - receive data + EP_Init(3, EP_TYPE_BULK, USB_TXBUFSZ, 0, transmit_Handler); // IN3 - transmit data + break; + default: + break; + } +} + +/* +bmRequestType: 76543210 +7 direction: 0 - host->device, 1 - device->host +65 type: 0 - standard, 1 - class, 2 - vendor +4..0 getter: 0 - device, 1 - interface, 2 - endpoint, 3 - other +*/ +/** + * Endpoint0 (control) handler + */ +void EP0_Handler(){ + uint16_t epstatus = USB->EPnR[0]; // EP0R on input -> return this value after modifications + uint8_t reqtype = setup_packet->bmRequestType & 0x7f; + uint8_t dev2host = (setup_packet->bmRequestType & 0x80) ? 1 : 0; + int rxflag = RX_FLAG(epstatus); + if(rxflag && SETUP_FLAG(epstatus)){ + switch(reqtype){ + case STANDARD_DEVICE_REQUEST_TYPE: // standard device request + if(dev2host){ + std_d2h_req(); + }else{ + std_h2d_req(); + EP_WriteIRQ(0, (uint8_t *)0, 0); + } + break; + case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request + if(setup_packet->bRequest == CLEAR_FEATURE){ + EP_WriteIRQ(0, (uint8_t *)0, 0); + } + break; + case VENDOR_REQUEST_TYPE: + vendor_handler(setup_packet); + break; + case CONTROL_REQUEST_TYPE: + switch(setup_packet->bRequest){ + case GET_LINE_CODING: + EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding)); + break; + case SET_LINE_CODING: // omit this for next stage, when data will come + break; + case SET_CONTROL_LINE_STATE: + usbON = 1; + clstate_handler(setup_packet->wValue); + break; + case SEND_BREAK: + usbON = 0; + break_handler(); + break; + default: + break; + } + if(setup_packet->bRequest != GET_LINE_CODING) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement + break; + default: + EP_WriteIRQ(0, (uint8_t *)0, 0); + } + }else if(rxflag){ // got data over EP0 or host acknowlegement + if(endpoints[0].rx_cnt){ + if(setup_packet->bRequest == SET_LINE_CODING){ + linecoding_handler((usb_LineCoding*)ep0databuf); + } + } + } else if(TX_FLAG(epstatus)){ // package transmitted + // now we can change address after enumeration + if ((USB->DADDR & USB_DADDR_ADD) != USB_Addr){ + USB->DADDR = USB_DADDR_EF | USB_Addr; + usbON = 0; + } + } + epstatus = KEEP_DTOG(USB->EPnR[0]); + if(rxflag) epstatus ^= USB_EPnR_STAT_TX; // start ZLP/data transmission + else epstatus &= ~USB_EPnR_STAT_TX; // or leave unchanged + // keep DTOGs, clear CTR_RX,TX, set RX VALID + USB->EPnR[0] = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX)) ^ USB_EPnR_STAT_RX; +} + +/** + * Write data to EP buffer (called from IRQ handler) + * @param number - EP number + * @param *buf - array with data + * @param size - its size + */ +void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){ + if(size > endpoints[number].txbufsz) size = endpoints[number].txbufsz; + uint16_t N2 = (size + 1) >> 1; + // the buffer is 16-bit, so we should copy data as it would be uint16_t + uint16_t *buf16 = (uint16_t *)buf; +#if defined USB1_16 + // very bad: what if `size` is odd? + uint32_t *out = (uint32_t *)endpoints[number].tx_buf; + for(int i = 0; i < N2; ++i, ++out){ + *out = buf16[i]; + } +#elif defined USB2_16 + // use memcpy instead? + for(int i = 0; i < N2; i++){ + endpoints[number].tx_buf[i] = buf16[i]; + } +#else +#error "Define USB1_16 or USB2_16" +#endif + USB_BTABLE->EP[number].USB_COUNT_TX = size; +} + +/** + * Write data to EP buffer (called outside IRQ handler) + * @param number - EP number + * @param *buf - array with data + * @param size - its size + */ +void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){ + EP_WriteIRQ(number, buf, size); + uint16_t status = KEEP_DTOG(USB->EPnR[number]); + // keep DTOGs, clear CTR_TX & set TX VALID to start transmission + USB->EPnR[number] = (status & ~(USB_EPnR_CTR_TX)) ^ USB_EPnR_STAT_TX; +} + +/* + * Copy data from EP buffer into user buffer area + * @param *buf - user array for data + * @return amount of data read + */ +int EP_Read(uint8_t number, uint8_t *buf){ + int sz = endpoints[number].rx_cnt; + if(!sz) return 0; + endpoints[number].rx_cnt = 0; +#if defined USB1_16 + int n = (sz + 1) >> 1; + uint32_t *in = (uint32_t*)endpoints[number].rx_buf; + uint16_t *out = (uint16_t*)buf; + for(int i = 0; i < n; ++i, ++in) + out[i] = *(uint16_t*)in; +#elif defined USB2_16 + // use memcpy instead? + for(int i = 0; i < sz; ++i) + buf[i] = endpoints[number].rx_buf[i]; +#else +#error "Define USB1_16 or USB2_16" +#endif + return sz; +} + + +static uint16_t lastaddr = LASTADDR_DEFAULT; +/** + * Endpoint initialisation + * @param number - EP num (0...7) + * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) + * @param txsz - transmission buffer size @ USB/CAN buffer + * @param rxsz - reception buffer size @ USB/CAN buffer + * @param uint16_t (*func)(ep_t *ep) - EP handler function + * @return 0 if all OK + */ +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ + if(number >= STM32ENDPOINTS) return 4; // out of configured amount + if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large + if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE/ACCESSZ) return 2; // out of btable + USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); + USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; + if(rxsz & 1 || rxsz > USB_BTABLE_SIZE) return 3; // wrong rx buffer size + uint16_t countrx = 0; + if(rxsz < 64) countrx = rxsz / 2; + else{ + if(rxsz & 0x1f) return 3; // should be multiple of 32 + countrx = 31 + rxsz / 32; + } + USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; + endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + endpoints[number].txbufsz = txsz; + lastaddr += txsz; + USB_BTABLE->EP[number].USB_COUNT_TX = 0; + USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; + endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + lastaddr += rxsz; + USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; + endpoints[number].func = func; + return 0; +} + +// standard IRQ handler +void USB_IRQ(){ + if(USB->ISTR & USB_ISTR_RESET){ + usbON = 0; + // Reinit registers + USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + // Endpoint 0 - CONTROL + // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! + lastaddr = LASTADDR_DEFAULT; + // clear address, leave only enable bit + USB->DADDR = USB_DADDR_EF; + if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ + return; + } + USB->ISTR = ~USB_ISTR_RESET; + } + if(USB->ISTR & USB_ISTR_CTR){ + // EP number + uint8_t n = USB->ISTR & USB_ISTR_EPID; + // copy status register + uint16_t epstatus = USB->EPnR[n]; + // copy received bytes amount + endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter + // check direction + if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) + if(n == 0){ // control endpoint + if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack + EP_Read(0, setupdatabuf); + // interrupt handler will be called later + }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf + EP_Read(0, ep0databuf); + } + } + } + // call EP handler + if(endpoints[n].func) endpoints[n].func(endpoints[n]); + } + if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep + usbON = 0; +#ifndef STM32F0 + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; +#else + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LPMODE; +#endif + USB->ISTR = ~USB_ISTR_SUSP; + } + if(USB->ISTR & USB_ISTR_WKUP){ // wakeup +#ifndef STM32F0 + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags +#else + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LPMODE); +#endif + USB->ISTR = ~USB_ISTR_WKUP; + } +} + +#if defined STM32F3 +void usb_lp_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F1 +void usb_lp_can_rx0_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F0 +void usb_isr() __attribute__ ((alias ("USB_IRQ"))); +#endif diff --git a/F1:F103/PL2303_rb_strip/usb_lib.h b/F1:F103/PL2303_rb_strip/usb_lib.h new file mode 100644 index 0000000..ec26927 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/usb_lib.h @@ -0,0 +1,172 @@ +/* + * Copyright 2024 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include +#include "usbhw.h" + +#define EP0DATABUF_SIZE (64) +#define LASTADDR_DEFAULT (STM32ENDPOINTS * 8) + +// bmRequestType & 0x7f +#define STANDARD_DEVICE_REQUEST_TYPE 0 +#define STANDARD_ENDPOINT_REQUEST_TYPE 2 +#define VENDOR_REQUEST_TYPE 0x40 +#define CONTROL_REQUEST_TYPE 0x21 +// bRequest, standard; for bmRequestType == 0x80 +#define GET_STATUS 0x00 +#define GET_DESCRIPTOR 0x06 +#define GET_CONFIGURATION 0x08 +// for bmRequestType == 0 +#define CLEAR_FEATURE 0x01 +#define SET_FEATURE 0x03 // unused +#define SET_ADDRESS 0x05 +#define SET_DESCRIPTOR 0x07 // unused +#define SET_CONFIGURATION 0x09 +// for bmRequestType == 0x81, 1 or 0xB2 +#define GET_INTERFACE 0x0A // unused +#define SET_INTERFACE 0x0B // unused +#define SYNC_FRAME 0x0C // unused +#define VENDOR_REQUEST 0x01 // unused + +// Class-Specific Control Requests +#define SEND_ENCAPSULATED_COMMAND 0x00 // unused +#define GET_ENCAPSULATED_RESPONSE 0x01 // unused +#define SET_COMM_FEATURE 0x02 // unused +#define GET_COMM_FEATURE 0x03 // unused +#define CLEAR_COMM_FEATURE 0x04 // unused +#define SET_LINE_CODING 0x20 +#define GET_LINE_CODING 0x21 +#define SET_CONTROL_LINE_STATE 0x22 +#define SEND_BREAK 0x23 + +// control line states +#define CONTROL_DTR 0x01 +#define CONTROL_RTS 0x02 + +// string descriptors +enum{ + iLANGUAGE_DESCR, + iMANUFACTURER_DESCR, + iPRODUCT_DESCR, + iSERIAL_DESCR, + iINTERFACE_DESCR, + iDESCR_AMOUNT +}; + +// Types of descriptors +#define DEVICE_DESCRIPTOR 0x01 +#define CONFIGURATION_DESCRIPTOR 0x02 +#define STRING_DESCRIPTOR 0x03 +#define DEVICE_QUALIFIER_DESCRIPTOR 0x06 + +#define RX_FLAG(epstat) (epstat & USB_EPnR_CTR_RX) +#define TX_FLAG(epstat) (epstat & USB_EPnR_CTR_TX) +#define SETUP_FLAG(epstat) (epstat & USB_EPnR_SETUP) + +// EPnR bits manipulation +#define KEEP_DTOG_STAT(EPnR) (EPnR & ~(USB_EPnR_STAT_RX|USB_EPnR_STAT_TX|USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX)) +#define KEEP_DTOG(EPnR) (EPnR & ~(USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX)) + +// EP types +#define EP_TYPE_BULK 0x00 +#define EP_TYPE_CONTROL 0x01 +#define EP_TYPE_ISO 0x02 +#define EP_TYPE_INTERRUPT 0x03 + +#define LANG_US (uint16_t)0x0409 + +#define _USB_STRING_(name, str) \ +static const struct name \ +{ \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint16_t bString[(sizeof(str) - 2) / 2]; \ + \ +} \ +name = {sizeof(name), 0x03, str} + +#define _USB_LANG_ID_(name, lng_id) \ + \ +static const struct name \ +{ \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint16_t bString; \ + \ +} \ +name = {0x04, 0x03, lng_id} + +// EP0 configuration packet +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} config_pack_t; + +// endpoints state +typedef struct{ + uint16_t *tx_buf; // transmission buffer address + uint16_t txbufsz; // transmission buffer size + uint8_t *rx_buf; // reception buffer address + void (*func)(); // endpoint action function + unsigned rx_cnt : 10; // received data counter +} ep_t; + +typedef struct { + uint32_t dwDTERate; + uint8_t bCharFormat; + #define USB_CDC_1_STOP_BITS 0 + #define USB_CDC_1_5_STOP_BITS 1 + #define USB_CDC_2_STOP_BITS 2 + uint8_t bParityType; + #define USB_CDC_NO_PARITY 0 + #define USB_CDC_ODD_PARITY 1 + #define USB_CDC_EVEN_PARITY 2 + #define USB_CDC_MARK_PARITY 3 + #define USB_CDC_SPACE_PARITY 4 + uint8_t bDataBits; +} __attribute__ ((packed)) usb_LineCoding; + +typedef struct { + uint8_t bmRequestType; + uint8_t bNotificationType; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} __attribute__ ((packed)) usb_cdc_notification; + +extern ep_t endpoints[]; +extern volatile uint8_t usbON; +extern config_pack_t *setup_packet; +extern uint8_t ep0databuf[], setupdatabuf[]; + +void EP0_Handler(); + +void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size); +void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size); +int EP_Read(uint8_t number, uint8_t *buf); +usb_LineCoding getLineCoding(); + +void linecoding_handler(usb_LineCoding *lc); +void clstate_handler(uint16_t val); +void break_handler(); +void vendor_handler(config_pack_t *packet); +void chkin(); +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)()); diff --git a/F1:F103/PL2303_rb_strip/usbhw.c b/F1:F103/PL2303_rb_strip/usbhw.c new file mode 100644 index 0000000..4f061b7 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/usbhw.c @@ -0,0 +1,63 @@ +/* + * Copyright 2024 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "usb.h" +#include "usb_lib.h" + +// here we suppose that all PIN settings done in hw_setup earlier +void USB_setup(){ +#if defined STM32F3 + NVIC_DisableIRQ(USB_LP_IRQn); + // remap USB LP & Wakeup interrupts to 75 and 76 - works only on pure F303 + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // enable tacting of SYSCFG + SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP; +#elif defined STM32F1 + NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); + NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); +#elif defined STM32F0 + NVIC_DisableIRQ(USB_IRQn); + RCC->APB1ENR |= RCC_APB1ENR_CRSEN; + RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB + RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48 + uint32_t tmout = 16000000; + while(!(RCC->CR2 & RCC_CR2_HSI48RDY)){if(--tmout == 0) break;} + FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; + CRS->CFGR &= ~CRS_CFGR_SYNCSRC; + CRS->CFGR |= CRS_CFGR_SYNCSRC_1; // USB SOF selected as sync source + CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim + CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only + RCC->CFGR |= RCC_CFGR_SW; +#endif + RCC->APB1ENR |= RCC_APB1ENR_USBEN; + //?? + USB->CNTR = USB_CNTR_FRES; // Force USB Reset + for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms + USB->CNTR = 0; + USB->BTABLE = 0; + USB->DADDR = 0; + USB->ISTR = 0; + USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts +#if defined STM32F3 + NVIC_EnableIRQ(USB_LP_IRQn); +#elif defined STM32F1 + NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); +#elif defined STM32F0 + USB->BCDR |= USB_BCDR_DPPU; + NVIC_EnableIRQ(USB_IRQn); +#endif +} + + diff --git a/F1:F103/PL2303_rb_strip/usbhw.h b/F1:F103/PL2303_rb_strip/usbhw.h new file mode 100644 index 0000000..9944700 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/usbhw.h @@ -0,0 +1,155 @@ +/* + * Copyright 2024 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#if defined STM32F0 +#include +#elif defined STM32F1 +#include +// there's no this define in standard header +#define USB_BASE ((uint32_t)0x40005C00) +#elif defined STM32F3 +#include +#endif + +// max endpoints number +#define STM32ENDPOINTS 8 +/** + * Buffers size definition + **/ + +// F0 - USB2_16; F1 - USB1_16; F3 - 1/2 depending on series +#if !defined USB1_16 && !defined USB2_16 +#if defined STM32F0 +#define USB2_16 +#elif defined STM32F1 +#define USB1_16 +#else +#error "Can't determine USB1_16 or USB2_16, define by hands" +#endif +#endif + +// BTABLE_SIZE FOR STM32F3: +// In STM32F303/302xB/C, 512 bytes SRAM is not shared with CAN. +// In STM32F302x6/x8 and STM32F30xxD/E, 726 bytes dedicated SRAM and 256 bytes shared SRAM with CAN i.e. +// 1Kbytes dedicated SRAM in case CAN is disabled. +// remember, that USB_BTABLE_SIZE will be divided by ACCESSZ, so don't divide it twice for 32-bit addressing + +#ifdef NOCAN +#if defined STM32F0 +#define USB_BTABLE_SIZE 1024 +#elif defined STM32F3 +#define USB_BTABLE_SIZE 512 +#warning "Please, check real buffer size due to docs" +#else +#error "define STM32F0 or STM32F3" +#endif +#else // !NOCAN: F0/F3 with CAN or F1 (can't simultaneously run CAN and USB) +#if defined STM32F0 +#define USB_BTABLE_SIZE 768 +#elif defined STM32F3 +#define USB_BTABLE_SIZE 512 +#warning "Please, check real buffer size due to docs" +#else // STM32F103: 1024 bytes but with 32-bit addressing +#define USB_BTABLE_SIZE 1024 +#endif +#endif // NOCAN + +// first 64 bytes of USB_BTABLE are registers! +//#define USB_EP0_BASEADDR 64 +// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303) +#define USB_EP0_BUFSZ 64 +// USB transmit buffer size (64 for PL2303) +#define USB_TXBUFSZ 64 +// USB receive buffer size (64 for PL2303) +#define USB_RXBUFSZ 64 +// EP1 - interrupt - buffer size +#define USB_EP1BUFSZ 8 + +#define USB_BTABLE_BASE 0x40006000 +#define USB ((USB_TypeDef *) USB_BASE) + +#ifdef USB_BTABLE +#undef USB_BTABLE +#endif +#define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE)) +#define USB_ISTR_EPID 0x0000000F +#define USB_FNR_LSOF_0 0x00000800 +#define USB_FNR_lSOF_1 0x00001000 +#define USB_LPMCSR_BESL_0 0x00000010 +#define USB_LPMCSR_BESL_1 0x00000020 +#define USB_LPMCSR_BESL_2 0x00000040 +#define USB_LPMCSR_BESL_3 0x00000080 +#define USB_EPnR_CTR_RX 0x00008000 +#define USB_EPnR_DTOG_RX 0x00004000 +#define USB_EPnR_STAT_RX 0x00003000 +#define USB_EPnR_STAT_RX_0 0x00001000 +#define USB_EPnR_STAT_RX_1 0x00002000 +#define USB_EPnR_SETUP 0x00000800 +#define USB_EPnR_EP_TYPE 0x00000600 +#define USB_EPnR_EP_TYPE_0 0x00000200 +#define USB_EPnR_EP_TYPE_1 0x00000400 +#define USB_EPnR_EP_KIND 0x00000100 +#define USB_EPnR_CTR_TX 0x00000080 +#define USB_EPnR_DTOG_TX 0x00000040 +#define USB_EPnR_STAT_TX 0x00000030 +#define USB_EPnR_STAT_TX_0 0x00000010 +#define USB_EPnR_STAT_TX_1 0x00000020 +#define USB_EPnR_EA 0x0000000F +#define USB_COUNTn_RX_BLSIZE 0x00008000 +#define USB_COUNTn_NUM_BLOCK 0x00007C00 +#define USB_COUNTn_RX 0x0000003F + +#define USB_TypeDef USB_TypeDef_custom + +typedef struct { + __IO uint32_t EPnR[STM32ENDPOINTS]; + __IO uint32_t RESERVED[STM32ENDPOINTS]; + __IO uint32_t CNTR; + __IO uint32_t ISTR; + __IO uint32_t FNR; + __IO uint32_t DADDR; + __IO uint32_t BTABLE; +} USB_TypeDef; + +// F303 D/E have 2x16 access scheme +typedef struct{ +#if defined USB2_16 + __IO uint16_t USB_ADDR_TX; + __IO uint16_t USB_COUNT_TX; + __IO uint16_t USB_ADDR_RX; + __IO uint16_t USB_COUNT_RX; +#define ACCESSZ (1) +#define BUFTYPE uint8_t +#elif defined USB1_16 + __IO uint32_t USB_ADDR_TX; + __IO uint32_t USB_COUNT_TX; + __IO uint32_t USB_ADDR_RX; + __IO uint32_t USB_COUNT_RX; +#define ACCESSZ (2) +#define BUFTYPE uint16_t +#else +#error "Define USB1_16 or USB2_16" +#endif +} USB_EPDATA_TypeDef; + + +typedef struct{ + __IO USB_EPDATA_TypeDef EP[STM32ENDPOINTS]; +} USB_BtableDef; + +void USB_setup(); diff --git a/F1:F103/PL2303_rb_strip/version.inc b/F1:F103/PL2303_rb_strip/version.inc new file mode 100644 index 0000000..505e794 --- /dev/null +++ b/F1:F103/PL2303_rb_strip/version.inc @@ -0,0 +1,2 @@ +#define BUILD_NUMBER "1" +#define BUILD_DATE "2024-09-02" diff --git a/F1:F103/PL2303_ringbuffer/Makefile b/F1:F103/PL2303_ringbuffer/Makefile index b3cf7a9..09f28fd 100644 --- a/F1:F103/PL2303_ringbuffer/Makefile +++ b/F1:F103/PL2303_ringbuffer/Makefile @@ -3,7 +3,8 @@ BINARY := PL2303 MCU ?= F103x6 # change this linking script depending on particular MCU model, LDSCRIPT ?= stm32f103x6.ld -DEFINES := -DUSB1_16 -DSTM32F10X_LD +#DEFINES := -DUSB1_16 -DSTM32F10X_LD +DEFINES := -DSTM32F10X_LD include ../makefile.f1 include ../../makefile.stm32 diff --git a/F1:F103/PL2303_ringbuffer/PL2303.bin b/F1:F103/PL2303_ringbuffer/PL2303.bin index 615b166171898b92ba7b11f3f638986062c844b6..1a54b2108ad7f3e0cd80fd285866b47aa40919cd 100755 GIT binary patch delta 3349 zcmbtWeQ*=U72mx(*|KbG$+EFzz9gMLh=oD6arlnUvN+q4jbcpFNyvvBtBJtMAcsjq z)3iE&5FlZuHfP!lkW?f+>_zA^;d?Y*h|ZVxVPypfdftePpxYsKRm z6-;;!Dk6-RDSF3hAk_U$B&fA9<8918Jh{DHSJP0=8r0QYneTYit5K*%kzri~HRRY^ zNdRSgtx^h=?S8~POZ-Iw>&;rBt9=>xMt4@VS-9v%o!LA##-j`3X!f<>x`@!&=zb-% zkQw;iAXNCl$bUBJ@()b{i}rPbNCMK^yq5X$XG=e$uY8$kA9=C zpck7E+fH(g?Ifqj^y_1jXV>s-lV|$68%dZc;nXR1<0cyXRzjHROi7#7M5t*b_+=ks z&x;@)_SOBy!fTSVpS(NRPZ(jVm`{C-Z6c<%;t^V>U5jbSPq$f_ z5l#}&h`XHx#1OqKbB}=nzR_$QQJt^or_6M)gX|R-G1Krq@gb%J?-jQ&h0wmwl==5P zxX7V2A(1w+e1LfBupu7p`nJ?=cHSrXTw|-k}XJKsQITH=z_HQ?Z5G#;?r7eUf zdw-~h?6U;O+M*Xj@3I}Cw$0ds&Ds3y0q~5uEYf_Shj@yTU0!*eL94<`6y~yx80r_I@8A#l-;a3knW(zTd9#IydfTa`L-#P zZ%l<1Ew^Wc(v8VLy>wd_qF5(n_#H>eS6L3e3dX)cczaX#~E{MsscqAE858hBh1%1 zzrY#)3}RDntR;+chskS3SldvYL{A)f&SaD24wGFC!^Eo@CV|Nvqam~qPv%#qV`?=P zwS#Sl4a6Kj?0#f3>b{Fya*YyWi! zvl+EaSdG}HIFn)`)*O%Si|0MX%v6q~eY(33IKFsv@7E{De5>#1D4Ac(nUh8k3*%zn zQDi)N)yFA$NV3C5Xgj|ShbAostE+CNt*7ikPcnDbb@Kc8LHbuJ_|5$@oxddkzlE0K zXm!7t*Akq(upi|>Z^rXcK`aQ=V}lej$V~ET@C`b7@5bw4V&U<&fkOALwCx6*sbyz z^1#v@KpgUeymz>!Vgoag`n<|~{93TCoh&qo3zIKq1~Zkuc4DPb0Vio&Ev8?sXeZ_3 zyp#onK?9o0Nvc)_ui;fJUS^+uoK)2(`;HSE`|0P-$cxXPBQ@)vUSR>}92dou`=-@s zK@z*#{-24fi}_N%e5PScKHLT+8)^oFNjvj*h_h)fq>Jm^hlqxIxDzzyq zSfuw&36=6-LZiHr8k?lW=Cn+6aOJH~vOJTHOxeEcSAZ)1>dIVx318rw5z_Mo{7m2e zD=&cDQn5GfmmqPTIt$uL_2ba)RkNC);{6bs?T>u;`~DCmOAq6JpzUW! zO$jbJ2CZDDWj-<$UK6U`aSZo}%JiJ1-#M~9o%Hh2H^kEP$MHr{Ot<)(of4`7Jc0~P zNlJA}i7C#Az^`{$@^`G^t~cjerA%r^L$lp_J%y=r;qZn!Jh8dR?%6$o8my5)YKSni z0Uc}YLqsinMn+oRx_M;%F?bI?BPUxn6Lze_b&R0Fv*g^o;tH#zpoW1uOGf5dB~1B; zfv|h5k!?@eU60y#K;3xMUM_9JdeS!InNs?u?)fpMb& zyyTmpGZOfT(;pG0f(VYYFRdxBF0a+PwLd-Uu6Jj-^IXb?QBu>mtmZSKYyosm3Db$d zDcL!#eymzGjpqp0bEfYw-0oRHxbdpO>cXny zgbTpqA49W&>d}5GulAelZB}qUtsB@#a(8b8mgr$4LIo>vbX$b0-`OX+WZ|-!K7sYh z{aFETSjeen_sm03O=n>8l%ODEJ7pIKl)H*&j9Dks}b~=nz`C~{; zamWBbm{X5IPC6y_2xLDP7a*W^-TzVbVC&Cs_;AUsC0|wkx8_g-0LpH zR@K5)X}cx2Yh$=O9(^X}sPf07?#aQWn6ft>eIhnWUW4Q zI#2~gY}u`Be@J%gH}F83+;25rYGmCIilRKQQ6D=LqWK+G%>`oZ`d*7pZoO*^w&vv=wcNPpGZ8N655 zsnC4L-{%r1owfQ_g>?-GIsrDyXCAuZl;S0qLUKsF5Qdikn*m$({Z}$Spu}@J^^}#% zE0$M3yxg|f@FaRtd|kIdysTSVvI|Os2e1@i0Za#|64Ve?#K}zt{Sc~0R#XV>DpZR~ fP_g)=zGZ$F17(AP1wZ&K8}1IeW9hC360p)#395Y8{*I=#2HScG*Z0&rQsV%Xpb+Of7@x! z+jb)f%gP+8q7G^mJ<%mABeFbM*-@jGQ1_6a;k3I34M{p?!e~gMg*|jd(n`ycanU+J z-Vj#GzM4O40@Nb|;;M{kNHQlJ!#&I_1MUhX@+|cjqD2qgX_N&x(Tf6(E^8)u z!%}dr(HjGbFH8fJo(}FMhlS(vTzo|MNM42y3sdqXur5xh@*HVeX<@WTpfx(ahlH9i z8;{B2%j-2f+Q;d%JO%sPGo|%9*lT!BOT#`o^FkQuyyS|ZGmK}kC)`Jl7<$N<;py;O zy1n7fJ=lr$Ieg&|)*^jXbbD_f2^o@YZIT?TR^UpxzUrpA7kdt`B{~re`JpV{1vmuo z9eoFW2ed+yQ5%mvFtap#zF$^cb+e&&o`s(1paNU*?s%+pMjKwNNd<`|GYiA>G|4~} z&SZrtofTp$iog#1uS=pQU)`ZKOL~XN2Kz86Odlqj zW^as!Q3ak2c!njj4htDfy2XL139o#VIIBMFCxbRl*xPrke+F9l=e&Na`}=0*R7Ee)6JB(ul@Ca*oJ)e4 zVmv_+_+!6|FXfY<^bWhv(cp@-PnG%GW zB*CL@*iTpk?Q;*Nui>-_lb5#3BKeTiH{x=>>C|6HbQz~l4InMn{h35HT_EcoZ0`p- zcRbc}3(nTM2QeRyy?W~#spO?d0o2}1+ey_2oypt<+qv&s0p?4!oM#6z>$;(HX)%s& z`1DP@n&9Ms59I^iip$Z`>EImum%bEhVkDo@@;<4A_sN`C3GRz4<#V&RQJfR#Q4h2U}{;9#VTQ+(7NrnEyasS#bLNtOic`U=9 z!MM8!MWbR)RCgG(&#vhrSlFVxZ;78pOF2=|A?MS1g%00epZ6hQnv>lh5}EGH%hu@A zPmU1f&d1gm;87#Ou(BvusRm8DjrE`8b{oOSa_)M1yFt6IR??W5a$h2&W2D={>XZWc z6%|Mb+fo**{iTS_=CjE+35dSJZ7EI^Q-vfeDxwWB*pc1 z24X5G#5!PVRMX((0>l`AM*ElVssP*|O_NO6!|1u4DLj>0oWbbIB-71Er+1&KC4;A+ zP`(sSrdEQPNUCJ)p0uqC{L8Z4DdFWjJfT&Rq(ZZ_a5ybP?|*PAoGfwXA#INP`qw~} ze*5)OzLGC?FAQh%#rz`oAHLoNdRGgV)1Cp1TT}~R-KE+L>!?bX?w7-aDD*@>duJd_ zNt%SD^j|+9InpFOp23_F9LWbTf>WQKJ9n-Y&hua|IZ`O$f1!{JP0O!B07BrPJ4-m9 zzQQ2IBmkpS!cB>YrR&cVWf?9z3+vox4r!N+duv~^yfaBZBdnO0pX9ORIJ@c9qt6Ph z^ETth1phpPXBW!1iej==OjKB-sBXQbrT&1crH&Ib&;k4U#+EfLwYzK&*=lX;YptSz z@e*C%%QinjJ!gq(??D%LeS1l@n1K)4jn|c_lB6~2U478iP+J}KR#%I1;5_V-X3N9& zW@k;EDY~z<+175u&eiq2rCRjt!`RkAQaiKw44bL0gA|yK66VZNq72~>UP%S$JsT6I zN0E+Q?A5>nIZ&SoxB%y`s8@T17hmhIGzsn99i^6{x-B+pa)WW0cx?bpjQxV^-da-> z(HHF9uBBj1hP&-D2O7eaw}aMbPYdYsWLQPS<<=F{r}CPHuSm~cwL|^r1xK@Efuq32 z*ctmpqHJaxSnF40j~D2&jkyDp(;lz*3hZplke(Bdc@MkBT;0aU1Kf=hUYo1k=)L}t zcZ8@ymPKy!PBX6fEP_)DLr6t&hy{SOt3oJ5LGC;VVXi70BPq{jL~$}0<>)dBNh5uB z1WVsii4Veipf)(bJ%BrnNEE!O6SNZMNALR)McQQWbOfd8zqGIZc&OE-j9}`>1g1V7 zI-k`)i9FB#t+5s#kH<{Y0iS6Riah5%NcuFCM~q`sToaTwDG`}cNoW-+=7T1m5z6{E zQ~1qzY|$;o7mppEzDU-Azg5v^dhd9?Irs^jTqGL+Here5?v2M1Z=u4f=vJV9G4TJ-Kzn>=OqcPP&x)))%2O^mEjY>1|k?D7#HwEK~ORNi5QfAtWSDlGqghQ_y-wL2RaryQGh|A63 zPWaO_9)_yfp`4Au*(uKWD>(av*ou}(KFo*BQTsn6bMTDM14zg5lDT;7-s!He^yL`I z8tBh_pAufqE>Er5_5}M-vypY!pRg;C@Im$iRp+1;4*;|Q*rc`uP$a0Nv~kkH(r(m- zN>Lg7uPj4b(4**a^dy|v(GzGJ+9BMV({5;zBNjnT%>AT$O)wSy_sp<+j*HO00ier? AQ~&?~ diff --git a/F1:F103/PL2303_ringbuffer/hardware.c b/F1:F103/PL2303_ringbuffer/hardware.c index 7a78b04..5ced42a 100644 --- a/F1:F103/PL2303_ringbuffer/hardware.c +++ b/F1:F103/PL2303_ringbuffer/hardware.c @@ -25,9 +25,9 @@ static inline void gpio_setup(){ // AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE; AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // for PA15 // Set led as opendrain output - //GPIOC->CRH |= CRH(13, CNF_ODOUTPUT | MODE_SLOW); + GPIOC->CRH |= CRH(13, CNF_ODOUTPUT | MODE_SLOW); // USB pullup (PA15) - pushpull output - GPIOA->CRH = CRH(8, CNF_PPOUTPUT | MODE_SLOW) | CRH(15, CNF_PPOUTPUT | MODE_SLOW); + GPIOA->CRH = /* CRH(8, CNF_PPOUTPUT | MODE_SLOW) | */ CRH(15, CNF_PPOUTPUT | MODE_SLOW); } void hw_setup(){ diff --git a/F1:F103/PL2303_ringbuffer/hardware.h b/F1:F103/PL2303_ringbuffer/hardware.h index 2763e34..107e451 100644 --- a/F1:F103/PL2303_ringbuffer/hardware.h +++ b/F1:F103/PL2303_ringbuffer/hardware.h @@ -22,13 +22,18 @@ // LED0 - PC13 (bluepill), blinking each second // PA8 - my board -#define LED0_port GPIOA -#define LED0_pin (1<<8) +#define LED0_port GPIOC +#define LED0_pin (1<<13) #define LED_blink(x) pin_toggle(x ## _port, x ## _pin) #define LED_on(x) pin_clear(x ## _port, x ## _pin) #define LED_off(x) pin_set(x ## _port, x ## _pin) +#define USBPU_port GPIOA +#define USBPU_pin (1<<15) +#define USBPU_ON() pin_set(USBPU_port, USBPU_pin) +#define USBPU_OFF() pin_clear(USBPU_port, USBPU_pin) + extern volatile uint32_t Tms; void hw_setup(); diff --git a/F1:F103/PL2303_ringbuffer/main.c b/F1:F103/PL2303_ringbuffer/main.c index 846aeb0..5a13f2e 100644 --- a/F1:F103/PL2303_ringbuffer/main.c +++ b/F1:F103/PL2303_ringbuffer/main.c @@ -33,9 +33,8 @@ int main(void){ char inbuff[MAXSTRLEN+1]; StartHSE(); hw_setup(); - SysTick_Config(72000); USBPU_OFF(); - hw_setup(); + SysTick_Config(72000); usart_setup(); USB_setup(); USBPU_ON(); @@ -56,6 +55,7 @@ int main(void){ if(l < 0) USB_sendstr("ERROR: USB buffer overflow or string was too long\n"); else if(l){ USEND("Got USB data\n"); + USB_sendstr("RECEIVED: _"); USB_sendstr(inbuff); USB_sendstr("_\n"); const char *ans = parse_cmd(inbuff); if(ans) USB_sendstr(ans); } diff --git a/F1:F103/PL2303_ringbuffer/pl2303.creator.user b/F1:F103/PL2303_ringbuffer/pl2303.creator.user index 0e70a42..1b1978a 100644 --- a/F1:F103/PL2303_ringbuffer/pl2303.creator.user +++ b/F1:F103/PL2303_ringbuffer/pl2303.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -8,7 +8,7 @@ ProjectExplorer.Project.ActiveTarget - 0 + 0 ProjectExplorer.Project.EditorSettings @@ -28,7 +28,7 @@ QmlJSGlobal - 2 + 2 KOI8-R false 4 @@ -37,6 +37,7 @@ true true 1 + 0 false true false @@ -54,6 +55,7 @@ *.md, *.MD, Makefile false true + true @@ -67,7 +69,9 @@ true true + false + 0 true @@ -75,6 +79,7 @@ true Builtin.DefaultTidyAndClazy 8 + false @@ -89,9 +94,9 @@ Desktop Desktop {65a14f9e-e008-4c1b-89df-4eaa4774b6e3} - 0 - 0 - 0 + 0 + 0 + 0 /Big/Data/00__Electronics/STM32/F303-nolib/blink @@ -102,9 +107,9 @@ true GenericProjectManager.GenericMakeStep - 1 - Сборка - Сборка + 1 + Build + Build ProjectExplorer.BuildSteps.Build @@ -115,9 +120,9 @@ true GenericProjectManager.GenericMakeStep - 1 - Очистка - Очистка + 1 + Clean + Clean ProjectExplorer.BuildSteps.Clean 2 @@ -128,12 +133,12 @@ Default GenericProjectManager.GenericBuildConfiguration - 1 + 1 - 0 - Развёртывание - Развёртывание + 0 + Deploy + Deploy ProjectExplorer.BuildSteps.Deploy 1 @@ -141,24 +146,29 @@ false ProjectExplorer.DefaultDeployConfiguration - 1 + 1 + true + true + true 2 + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + ProjectExplorer.CustomExecutableRunConfiguration - false + false true - false true - 1 + 1 ProjectExplorer.Project.TargetCount - 1 + 1 ProjectExplorer.Project.Updater.FileVersion diff --git a/F1:F103/PL2303_ringbuffer/proto.c b/F1:F103/PL2303_ringbuffer/proto.c index b56ac7a..11c719c 100644 --- a/F1:F103/PL2303_ringbuffer/proto.c +++ b/F1:F103/PL2303_ringbuffer/proto.c @@ -17,10 +17,9 @@ */ #include "proto.h" +#include "hardware.h" #include "usb.h" -extern uint32_t Tms; - const char *test = "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789S123456789T123456789U123456789V123456789W123456789X123456789Y"; char *omit_spaces(const char *buf){ diff --git a/F1:F103/PL2303_ringbuffer/ringbuffer.c b/F1:F103/PL2303_ringbuffer/ringbuffer.c index 0d10cd7..8d8d6ca 100644 --- a/F1:F103/PL2303_ringbuffer/ringbuffer.c +++ b/F1:F103/PL2303_ringbuffer/ringbuffer.c @@ -1,5 +1,4 @@ /* - * This file is part of the pl2303 project. * Copyright 2023 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify @@ -18,19 +17,21 @@ #include "ringbuffer.h" -// stored data length -int RB_datalen(ringbuffer *b){ +static int datalen(ringbuffer *b){ if(b->tail >= b->head) return (b->tail - b->head); else return (b->length - b->head + b->tail); } -/** - * @brief RB_hasbyte - check if buffer has given byte stored - * @param b - buffer - * @param byte - byte to find - * @return index if found, -1 if none - */ -int RB_hasbyte(ringbuffer *b, uint8_t byte){ +// stored data length +int RB_datalen(ringbuffer *b){ + if(b->busy) return -1; + b->busy = 1; + int l = datalen(b); + b->busy = 0; + return l; +} + +static int hasbyte(ringbuffer *b, uint8_t byte){ if(b->head == b->tail) return -1; // no data in buffer int startidx = b->head; if(b->head > b->tail){ // @@ -43,6 +44,20 @@ int RB_hasbyte(ringbuffer *b, uint8_t byte){ return -1; } +/** + * @brief RB_hasbyte - check if buffer has given byte stored + * @param b - buffer + * @param byte - byte to find + * @return index if found, -1 if none or busy + */ +int RB_hasbyte(ringbuffer *b, uint8_t byte){ + if(b->busy) return -1; + b->busy = 1; + int ret = hasbyte(b, byte); + b->busy = 0; + return ret; +} + // poor memcpy static void mcpy(uint8_t *targ, const uint8_t *src, int l){ while(l--) *targ++ = *src++; @@ -54,15 +69,8 @@ TRUE_INLINE void incr(ringbuffer *b, volatile int *what, int n){ if(*what >= b->length) *what -= b->length; } -/** - * @brief RB_read - read data from ringbuffer - * @param b - buffer - * @param s - array to write data - * @param len - max len of `s` - * @return bytes read - */ -int RB_read(ringbuffer *b, uint8_t *s, int len){ - int l = RB_datalen(b); +static int read(ringbuffer *b, uint8_t *s, int len){ + int l = datalen(b); if(!l) return 0; if(l > len) l = len; int _1st = b->length - b->head; @@ -78,33 +86,49 @@ int RB_read(ringbuffer *b, uint8_t *s, int len){ return _1st; } +/** + * @brief RB_read - read data from ringbuffer + * @param b - buffer + * @param s - array to write data + * @param len - max len of `s` + * @return bytes read or -1 if busy + */ +int RB_read(ringbuffer *b, uint8_t *s, int len){ + if(b->busy) return -1; + b->busy = 1; + int r = read(b, s, len); + b->busy = 0; + return r; +} + +static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){ + int idx = hasbyte(b, byte); + if(idx < 0) return 0; + int partlen = idx + 1 - b->head; + // now calculate length of new data portion + if(idx < b->head) partlen += b->length; + if(partlen > len) return -read(b, s, len); + return read(b, s, partlen); +} + /** * @brief RB_readto fill array `s` with data until byte `byte` (with it) * @param b - ringbuffer * @param byte - check byte * @param s - buffer to write data * @param len - length of `s` - * @return amount of bytes written (negative, if lenhead; - // now calculate length of new data portion - if(idx < b->head) partlen += b->length; - if(partlen > len) return -RB_read(b, s, len); - return RB_read(b, s, partlen); + if(b->busy) return -1; + b->busy = 1; + int n = readto(b, byte, s, len); + b->busy = 0; + return n; } -/** - * @brief RB_write - write some data to ringbuffer - * @param b - buffer - * @param str - data - * @param l - length - * @return amount of bytes written - */ -int RB_write(ringbuffer *b, const uint8_t *str, int l){ - int r = b->length - 1 - RB_datalen(b); // rest length +static int write(ringbuffer *b, const uint8_t *str, int l){ + int r = b->length - 1 - datalen(b); // rest length if(l > r) l = r; if(!l) return 0; int _1st = b->length - b->tail; @@ -117,8 +141,27 @@ int RB_write(ringbuffer *b, const uint8_t *str, int l){ return l; } +/** + * @brief RB_write - write some data to ringbuffer + * @param b - buffer + * @param str - data + * @param l - length + * @return amount of bytes written or -1 if busy + */ +int RB_write(ringbuffer *b, const uint8_t *str, int l){ + if(b->busy) return -1; + b->busy = 1; + int w = write(b, str, l); + b->busy = 0; + return w; +} + // just delete all information in buffer `b` -void RB_clearbuf(ringbuffer *b){ +int RB_clearbuf(ringbuffer *b){ + if(b->busy) return -1; + b->busy = 1; b->head = 0; b->tail = 0; + b->busy = 0; + return 1; } diff --git a/F1:F103/PL2303_ringbuffer/ringbuffer.h b/F1:F103/PL2303_ringbuffer/ringbuffer.h index 34daa76..ed2cf95 100644 --- a/F1:F103/PL2303_ringbuffer/ringbuffer.h +++ b/F1:F103/PL2303_ringbuffer/ringbuffer.h @@ -1,5 +1,4 @@ /* - * This file is part of the pl2303 project. * Copyright 2023 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify @@ -17,13 +16,21 @@ */ #pragma once + +#if defined STM32F0 +#include +#elif defined STM32F1 #include +#elif defined STM32F3 +#include +#endif typedef struct{ uint8_t *data; // data buffer const int length; // its length int head; // head index int tail; // tail index + volatile int busy; // == TRUE if buffer is busy now } ringbuffer; int RB_read(ringbuffer *b, uint8_t *s, int len); @@ -31,5 +38,4 @@ int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len); int RB_hasbyte(ringbuffer *b, uint8_t byte); int RB_write(ringbuffer *b, const uint8_t *str, int l); int RB_datalen(ringbuffer *b); -void RB_clearbuf(ringbuffer *b); - +int RB_clearbuf(ringbuffer *b); diff --git a/F1:F103/PL2303_ringbuffer/usart.h b/F1:F103/PL2303_ringbuffer/usart.h index 5bfb86d..7a8c07c 100644 --- a/F1:F103/PL2303_ringbuffer/usart.h +++ b/F1:F103/PL2303_ringbuffer/usart.h @@ -30,16 +30,6 @@ // macro for static strings #define USEND(str) usart_send(str) -#ifdef EBUG -#define x__(a) #a -#define STR(a) x__(a) -#define DBG(str) do{usart_send(__FILE__ " (L" STR(__LINE__) "): " str); \ - usart_putchar('\n'); usart_transmit(); }while(0) -#else -#define DBG(str) -#endif - - #define usartrx() (usart_linerdy) #define usartovr() (usart_bufovr) diff --git a/F1:F103/PL2303_ringbuffer/usb.c b/F1:F103/PL2303_ringbuffer/usb.c index 553b6cf..a2ee479 100644 --- a/F1:F103/PL2303_ringbuffer/usb.c +++ b/F1:F103/PL2303_ringbuffer/usb.c @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,18 +26,22 @@ static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending da static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ]; volatile ringbuffer rbout = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0}; volatile ringbuffer rbin = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0}; -// transmission is succesfull -volatile uint8_t bufisempty = 1; +// inbuf overflow when receiving volatile uint8_t bufovrfl = 0; +// last send data size +static volatile int lastdsz = 0; +// called from transmit EP void send_next(){ - if(bufisempty) return; - static int lastdsz = 0; int buflen = RB_read((ringbuffer*)&rbout, (uint8_t*)usbbuff, USB_TXBUFSZ); - if(!buflen){ + if(buflen == 0){ if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send lastdsz = 0; - bufisempty = 1; + return; + }else if(buflen < 0){ + lastdsz = 0; + // Uncomment next line if you want 4Mbit/s instead of 6Mbit/s + //EP_Write(3, NULL, 0); // send ZLP if buffer is in writting state now return; } EP_Write(3, (uint8_t*)usbbuff, buflen); @@ -47,44 +50,42 @@ void send_next(){ // blocking send full content of ring buffer int USB_sendall(){ - while(!bufisempty){ - if(!usbON) return 0; + while(lastdsz > 0){ + if(!usbON) return FALSE; } - return 1; + return TRUE; } // put `buf` into queue to send int USB_send(const uint8_t *buf, int len){ - if(!buf || !usbON || !len) return 0; + if(!buf || !usbON || !len) return FALSE; while(len){ int a = RB_write((ringbuffer*)&rbout, buf, len); - len -= a; - buf += a; - if(bufisempty){ - bufisempty = 0; - send_next(); - } + if(a > 0){ + len -= a; + buf += a; + } else if (a < 0) continue; // do nothing if buffer is in reading state + if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN } - return 1; + return TRUE; } int USB_putbyte(uint8_t byte){ - if(!usbON) return 0; - while(0 == RB_write((ringbuffer*)&rbout, &byte, 1)){ - if(bufisempty){ - bufisempty = 0; - send_next(); - } + if(!usbON) return FALSE; + int l = 0; + while((l = RB_write((ringbuffer*)&rbout, &byte, 1)) != 1){ + if(l < 0) continue; } - return 1; + if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN + return TRUE; } int USB_sendstr(const char *string){ - if(!string || !usbON) return 0; + if(!string || !usbON) return FALSE; int len = 0; const char *b = string; while(*b++) ++len; - if(!len) return 0; + if(!len) return FALSE; return USB_send((const uint8_t*)string, len); } @@ -95,13 +96,14 @@ int USB_sendstr(const char *string){ * @return amount of received bytes (negative, if overfull happened) */ int USB_receive(uint8_t *buf, int len){ - int sz = RB_read((ringbuffer*)&rbin, buf, len); + chkin(); if(bufovrfl){ - RB_clearbuf((ringbuffer*)&rbin); - if(!sz) sz = -1; - else sz = -sz; + while(1 != RB_clearbuf((ringbuffer*)&rbin)); bufovrfl = 0; + return -1; } + int sz = RB_read((ringbuffer*)&rbin, buf, len); + if(sz < 0) return 0; // buffer in writting state return sz; } @@ -112,15 +114,22 @@ int USB_receive(uint8_t *buf, int len){ * @return strlen or negative value indicating overflow (if so, string won't be ends with 0 and buffer should be cleared) */ int USB_receivestr(char *buf, int len){ - int l = RB_readto((ringbuffer*)&rbin, '\n', (uint8_t*)buf, len); - if(l == 0) return 0; - if(--l < 0 || bufovrfl) RB_clearbuf((ringbuffer*)&rbin); - else buf[l] = 0; // replace '\n' with strend + chkin(); if(bufovrfl){ - if(l > 0) l = -l; - else l = -1; + while(1 != RB_clearbuf((ringbuffer*)&rbin)); bufovrfl = 0; + return -1; } + int l = RB_readto((ringbuffer*)&rbin, '\n', (uint8_t*)buf, len); + if(l < 1){ + if(rbin.length == RB_datalen((ringbuffer*)&rbin)){ // buffer is full but no '\n' found + while(1 != RB_clearbuf((ringbuffer*)&rbin)); + return -1; + } + return 0; + } + if(l == 0) return 0; + buf[l-1] = 0; // replace '\n' with strend return l; } diff --git a/F1:F103/PL2303_ringbuffer/usb.h b/F1:F103/PL2303_ringbuffer/usb.h index 2a58624..4583b9b 100644 --- a/F1:F103/PL2303_ringbuffer/usb.h +++ b/F1:F103/PL2303_ringbuffer/usb.h @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,25 +16,25 @@ */ #pragma once + #include "ringbuffer.h" #include "usbhw.h" // sizes of ringbuffers for outgoing and incoming data #define RBOUTSZ (512) -#define RBINSZ (512) +#define RBINSZ (256) #define newline() USB_putbyte('\n') #define USND(s) do{USB_sendstr(s); USB_putbyte('\n');}while(0) -#if 0 #define STR_HELPER(s) #s #define STR(s) STR_HELPER(s) + #ifdef EBUG #define DBG(str) do{USB_sendstr(__FILE__ " (L" STR(__LINE__) "): " str); newline();}while(0) #else #define DBG(str) #endif -#endif extern volatile ringbuffer rbout, rbin; extern volatile uint8_t bufisempty, bufovrfl; diff --git a/F1:F103/PL2303_ringbuffer/usb_lib.c b/F1:F103/PL2303_ringbuffer/usb_lib.c index 49eb681..aea5344 100644 --- a/F1:F103/PL2303_ringbuffer/usb_lib.c +++ b/F1:F103/PL2303_ringbuffer/usb_lib.c @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include #include "usb.h" #include "usb_lib.h" @@ -26,7 +24,7 @@ ep_t endpoints[STM32ENDPOINTS]; static uint16_t USB_Addr = 0; static usb_LineCoding lineCoding = {115200, 0, 0, 8}; uint8_t ep0databuf[EP0DATABUF_SIZE], setupdatabuf[EP0DATABUF_SIZE]; -static config_pack_t *setup_packet = (config_pack_t*) setupdatabuf; +config_pack_t *setup_packet = (config_pack_t*) setupdatabuf; usb_LineCoding getLineCoding(){return lineCoding;} @@ -131,7 +129,7 @@ _USB_LANG_ID_(LD, LANG_US); _USB_STRING_(SD, u"0.0.1"); _USB_STRING_(MD, u"Prolific Technology Inc."); _USB_STRING_(PD, u"USB-Serial Controller"); -_USB_STRING_(ID, u"pl2303_emulator"); +_USB_STRING_(ID, u"USB-STM32"); static void const *StringDescriptor[iDESCR_AMOUNT] = { [iLANGUAGE_DESCR] = &LD, [iMANUFACTURER_DESCR] = &MD, @@ -266,15 +264,29 @@ static void transmit_Handler(){ // EP3IN send_next(); } +static uint8_t volatile rcvbuf[USB_RXBUFSZ]; +static uint8_t volatile rcvbuflen = 0; + +void chkin(){ + if(bufovrfl) return; + if(!rcvbuflen) return; + int w = RB_write((ringbuffer*)&rbin, (uint8_t*)rcvbuf, rcvbuflen); + if(w < 0) return; + if(w != rcvbuflen) bufovrfl = 1; + rcvbuflen = 0; + uint16_t status = KEEP_DTOG(USB->EPnR[2]); // don't change DTOG + USB->EPnR[2] = status ^ USB_EPnR_STAT_RX; +} + +// receiver reads data from local buffer and only then ACK'ed static void receive_Handler(){ // EP2OUT - uint8_t buf[USB_RXBUFSZ]; - uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]); - uint8_t sz = EP_Read(2, (uint8_t*)buf); - if(sz){ - if(RB_write((ringbuffer*)&rbin, buf, sz) != sz) bufovrfl = 1; + uint16_t status = KEEP_DTOG_STAT(USB->EPnR[2]); // don't change DTOG and NACK + if(rcvbuflen){ + bufovrfl = 1; // lost last data + rcvbuflen = 0; } - // keep stat_tx & set ACK rx, clear RX ctr - USB->EPnR[2] = (epstatus & ~USB_EPnR_CTR_RX) ^ USB_EPnR_STAT_RX; + rcvbuflen = EP_Read(2, (uint8_t*)rcvbuf); + USB->EPnR[2] = status & ~USB_EPnR_CTR_RX; } static inline void std_h2d_req(){ @@ -436,3 +448,103 @@ int EP_Read(uint8_t number, uint8_t *buf){ return sz; } + +static uint16_t lastaddr = LASTADDR_DEFAULT; +/** + * Endpoint initialisation + * @param number - EP num (0...7) + * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) + * @param txsz - transmission buffer size @ USB/CAN buffer + * @param rxsz - reception buffer size @ USB/CAN buffer + * @param uint16_t (*func)(ep_t *ep) - EP handler function + * @return 0 if all OK + */ +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ + if(number >= STM32ENDPOINTS) return 4; // out of configured amount + if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large + if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE/ACCESSZ) return 2; // out of btable + USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); + USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; + if(rxsz & 1 || rxsz > USB_BTABLE_SIZE) return 3; // wrong rx buffer size + uint16_t countrx = 0; + if(rxsz < 64) countrx = rxsz / 2; + else{ + if(rxsz & 0x1f) return 3; // should be multiple of 32 + countrx = 31 + rxsz / 32; + } + USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; + endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + endpoints[number].txbufsz = txsz; + lastaddr += txsz; + USB_BTABLE->EP[number].USB_COUNT_TX = 0; + USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; + endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + lastaddr += rxsz; + USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; + endpoints[number].func = func; + return 0; +} + +// standard IRQ handler +void USB_IRQ(){ + if(USB->ISTR & USB_ISTR_RESET){ + usbON = 0; + // Reinit registers + USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + // Endpoint 0 - CONTROL + // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! + lastaddr = LASTADDR_DEFAULT; + // clear address, leave only enable bit + USB->DADDR = USB_DADDR_EF; + if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ + return; + } + USB->ISTR = ~USB_ISTR_RESET; + } + if(USB->ISTR & USB_ISTR_CTR){ + // EP number + uint8_t n = USB->ISTR & USB_ISTR_EPID; + // copy status register + uint16_t epstatus = USB->EPnR[n]; + // copy received bytes amount + endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter + // check direction + if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) + if(n == 0){ // control endpoint + if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack + EP_Read(0, setupdatabuf); + // interrupt handler will be called later + }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf + EP_Read(0, ep0databuf); + } + } + } + // call EP handler + if(endpoints[n].func) endpoints[n].func(endpoints[n]); + } + if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep + usbON = 0; +#ifndef STM32F0 + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; +#else + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LPMODE; +#endif + USB->ISTR = ~USB_ISTR_SUSP; + } + if(USB->ISTR & USB_ISTR_WKUP){ // wakeup +#ifndef STM32F0 + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags +#else + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LPMODE); +#endif + USB->ISTR = ~USB_ISTR_WKUP; + } +} + +#if defined STM32F3 +void usb_lp_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F1 +void usb_lp_can_rx0_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F0 +void usb_isr() __attribute__ ((alias ("USB_IRQ"))); +#endif diff --git a/F1:F103/PL2303_ringbuffer/usb_lib.h b/F1:F103/PL2303_ringbuffer/usb_lib.h index d509e4f..ec26927 100644 --- a/F1:F103/PL2303_ringbuffer/usb_lib.h +++ b/F1:F103/PL2303_ringbuffer/usb_lib.h @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,8 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once + #include #include "usbhw.h" @@ -155,6 +154,7 @@ typedef struct { extern ep_t endpoints[]; extern volatile uint8_t usbON; +extern config_pack_t *setup_packet; extern uint8_t ep0databuf[], setupdatabuf[]; void EP0_Handler(); @@ -168,3 +168,5 @@ void linecoding_handler(usb_LineCoding *lc); void clstate_handler(uint16_t val); void break_handler(); void vendor_handler(config_pack_t *packet); +void chkin(); +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)()); diff --git a/F1:F103/PL2303_ringbuffer/usbhw.c b/F1:F103/PL2303_ringbuffer/usbhw.c index ac73fcf..4f061b7 100644 --- a/F1:F103/PL2303_ringbuffer/usbhw.c +++ b/F1:F103/PL2303_ringbuffer/usbhw.c @@ -1,6 +1,5 @@ /* - * This file is part of the MLX90640 project. - * Copyright 2022 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,109 +14,50 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include "usb.h" -#include "usbhw.h" #include "usb_lib.h" +// here we suppose that all PIN settings done in hw_setup earlier void USB_setup(){ +#if defined STM32F3 + NVIC_DisableIRQ(USB_LP_IRQn); + // remap USB LP & Wakeup interrupts to 75 and 76 - works only on pure F303 + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // enable tacting of SYSCFG + SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP; +#elif defined STM32F1 NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); - USBPU_OFF(); +#elif defined STM32F0 + NVIC_DisableIRQ(USB_IRQn); + RCC->APB1ENR |= RCC_APB1ENR_CRSEN; + RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB + RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48 + uint32_t tmout = 16000000; + while(!(RCC->CR2 & RCC_CR2_HSI48RDY)){if(--tmout == 0) break;} + FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; + CRS->CFGR &= ~CRS_CFGR_SYNCSRC; + CRS->CFGR |= CRS_CFGR_SYNCSRC_1; // USB SOF selected as sync source + CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim + CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only + RCC->CFGR |= RCC_CFGR_SW; +#endif RCC->APB1ENR |= RCC_APB1ENR_USBEN; - RCC->APB2ENR |= USB_RCC; + //?? USB->CNTR = USB_CNTR_FRES; // Force USB Reset for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms - //uint32_t ctr = 0; USB->CNTR = 0; USB->BTABLE = 0; USB->DADDR = 0; USB->ISTR = 0; USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts +#if defined STM32F3 + NVIC_EnableIRQ(USB_LP_IRQn); +#elif defined STM32F1 NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); - USBPU_ON(); +#elif defined STM32F0 + USB->BCDR |= USB_BCDR_DPPU; + NVIC_EnableIRQ(USB_IRQn); +#endif } -static uint16_t lastaddr = LASTADDR_DEFAULT; -/** - * Endpoint initialisation - * @param number - EP num (0...7) - * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) - * @param txsz - transmission buffer size @ USB/CAN buffer - * @param rxsz - reception buffer size @ USB/CAN buffer - * @param uint16_t (*func)(ep_t *ep) - EP handler function - * @return 0 if all OK - */ -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ - if(number >= STM32ENDPOINTS) return 4; // out of configured amount - if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large - if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable - USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); - USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; - if(rxsz & 1 || rxsz > 512) return 3; // wrong rx buffer size - uint16_t countrx = 0; - if(rxsz < 64) countrx = rxsz / 2; - else{ - if(rxsz & 0x1f) return 3; // should be multiple of 32 - countrx = 31 + rxsz / 32; - } - USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; - endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); - endpoints[number].txbufsz = txsz; - lastaddr += txsz; - USB_BTABLE->EP[number].USB_COUNT_TX = 0; - USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; - endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); - lastaddr += rxsz; - USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; - endpoints[number].func = func; - return 0; -} -// standard IRQ handler -void usb_lp_can_rx0_isr(){ - if(USB->ISTR & USB_ISTR_RESET){ - usbON = 0; - // Reinit registers - USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; - // Endpoint 0 - CONTROL - // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! - lastaddr = LASTADDR_DEFAULT; - // clear address, leave only enable bit - USB->DADDR = USB_DADDR_EF; - if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ - return; - } - USB->ISTR = ~USB_ISTR_RESET; - } - if(USB->ISTR & USB_ISTR_CTR){ - // EP number - uint8_t n = USB->ISTR & USB_ISTR_EPID; - // copy status register - uint16_t epstatus = USB->EPnR[n]; - // copy received bytes amount - endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter - // check direction - if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) - if(n == 0){ // control endpoint - if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack - EP_Read(0, setupdatabuf); - // interrupt handler will be called later - }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf - EP_Read(0, ep0databuf); - } - } - } - // call EP handler - if(endpoints[n].func) endpoints[n].func(endpoints[n]); - } - if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep - usbON = 0; - USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; - USB->ISTR = ~USB_ISTR_SUSP; - } - if(USB->ISTR & USB_ISTR_WKUP){ // wakeup - USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags - USB->ISTR = ~USB_ISTR_WKUP; - } -} diff --git a/F1:F103/PL2303_ringbuffer/usbhw.h b/F1:F103/PL2303_ringbuffer/usbhw.h index fadac61..9944700 100644 --- a/F1:F103/PL2303_ringbuffer/usbhw.h +++ b/F1:F103/PL2303_ringbuffer/usbhw.h @@ -1,6 +1,5 @@ /* - * This file is part of the MLX90640 project. - * Copyright 2022 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,22 +14,63 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once -#include -#define USB_RCC RCC_APB2ENR_IOPAEN -#define USBPU_port GPIOA -#define USBPU_pin (1<<15) -#define USBPU_ON() pin_clear(USBPU_port, USBPU_pin) -#define USBPU_OFF() pin_set(USBPU_port, USBPU_pin) +#if defined STM32F0 +#include +#elif defined STM32F1 +#include +// there's no this define in standard header +#define USB_BASE ((uint32_t)0x40005C00) +#elif defined STM32F3 +#include +#endif // max endpoints number #define STM32ENDPOINTS 8 /** * Buffers size definition **/ + +// F0 - USB2_16; F1 - USB1_16; F3 - 1/2 depending on series +#if !defined USB1_16 && !defined USB2_16 +#if defined STM32F0 +#define USB2_16 +#elif defined STM32F1 +#define USB1_16 +#else +#error "Can't determine USB1_16 or USB2_16, define by hands" +#endif +#endif + +// BTABLE_SIZE FOR STM32F3: +// In STM32F303/302xB/C, 512 bytes SRAM is not shared with CAN. +// In STM32F302x6/x8 and STM32F30xxD/E, 726 bytes dedicated SRAM and 256 bytes shared SRAM with CAN i.e. +// 1Kbytes dedicated SRAM in case CAN is disabled. +// remember, that USB_BTABLE_SIZE will be divided by ACCESSZ, so don't divide it twice for 32-bit addressing + +#ifdef NOCAN +#if defined STM32F0 +#define USB_BTABLE_SIZE 1024 +#elif defined STM32F3 #define USB_BTABLE_SIZE 512 +#warning "Please, check real buffer size due to docs" +#else +#error "define STM32F0 or STM32F3" +#endif +#else // !NOCAN: F0/F3 with CAN or F1 (can't simultaneously run CAN and USB) +#if defined STM32F0 +#define USB_BTABLE_SIZE 768 +#elif defined STM32F3 +#define USB_BTABLE_SIZE 512 +#warning "Please, check real buffer size due to docs" +#else // STM32F103: 1024 bytes but with 32-bit addressing +#define USB_BTABLE_SIZE 1024 +#endif +#endif // NOCAN + +// first 64 bytes of USB_BTABLE are registers! +//#define USB_EP0_BASEADDR 64 // for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303) #define USB_EP0_BUFSZ 64 // USB transmit buffer size (64 for PL2303) @@ -41,7 +81,6 @@ #define USB_EP1BUFSZ 8 #define USB_BTABLE_BASE 0x40006000 -#define USB_BASE ((uint32_t)0x40005C00) #define USB ((USB_TypeDef *) USB_BASE) #ifdef USB_BTABLE @@ -87,6 +126,7 @@ typedef struct { __IO uint32_t BTABLE; } USB_TypeDef; +// F303 D/E have 2x16 access scheme typedef struct{ #if defined USB2_16 __IO uint16_t USB_ADDR_TX; @@ -107,9 +147,9 @@ typedef struct{ #endif } USB_EPDATA_TypeDef; + typedef struct{ __IO USB_EPDATA_TypeDef EP[STM32ENDPOINTS]; } USB_BtableDef; void USB_setup(); -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)()); diff --git a/F1:F103/PL2303_ringbuffer/version.inc b/F1:F103/PL2303_ringbuffer/version.inc index 1f9f21d..f26fd71 100644 --- a/F1:F103/PL2303_ringbuffer/version.inc +++ b/F1:F103/PL2303_ringbuffer/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "80" -#define BUILD_DATE "2023-06-11" +#define BUILD_NUMBER "99" +#define BUILD_DATE "2024-09-02" diff --git a/F1:F103/Readme.md b/F1:F103/Readme.md index 747d3aa..384effa 100644 --- a/F1:F103/Readme.md +++ b/F1:F103/Readme.md @@ -2,9 +2,6 @@ - **BMP280** - I2C temperature/pressure sensor BMP280 and temp/pres/humidity sensor BME280 - **Canon_managing_device** - device for independent managing of some Canon lens - **canUART** - UART-CAN bridge -- **CDC_ACM** - simplest CDC-ACM snippet (*deprecated*) -- **chronometer** - first version of chronometer for bike/auto/moto competitions -- **chronometer_v2** - chrono-2 - **chronometer_v3** - chrono-3 - **DHT22_DHT11** - DHT11 and DHT22 humidity/temperature sensors management based on timer+DMA - **DS18** - DS18x20 temperature sensor management @@ -14,11 +11,8 @@ - **led_blink** - simple blink - **LED_Screen** - management with matrixes of LED screens 32x16 (or another size) pixels (P10) - **MAX7219_screen** - work with N LED matrices 8x8 -- **MLX90640** - test of MLX90640 (*deprecated* as can't calculate so many sqrt's on STM32F103) -- **PL2303** - based PL2303 emulation (*deprecated*) -- **PL2303_ringbuffer** - PL2303 with ringbuffer (need rebuld as for STM32F0x2) -- **pl2303_snippet** - (*deprecated*) -- **pl2303_snippet_naked** - (*deprecated*) +- **PL2303_rb_strip** - "naked" PL2303 (without UART) +- **PL2303_ringbuffer** - PL2303 with ringbuffer - **pwmdmatest** - generate signals on PA8 by PWM through DMA @ TIM1_CC1 (awfull code) - **pwmtest** - generate signals on PA8 by PWM @ TIM1_CC1 - **RGB_LED_Screen** - HUB75E-based RGB LED panel management, 8.8.4 color (RRRGGGBB) diff --git a/F1:F103/STM32F103C.md b/F1:F103/STM32F103C.md index 4968e45..2aa85ad 100644 --- a/F1:F103/STM32F103C.md +++ b/F1:F103/STM32F103C.md @@ -1,4 +1,4 @@ -| **Pin #** | **Pin name ** | **function** | **settings** | **comment ** | +| Pin # | Pin name | function | settings | comment | | --------- | ------------- | ------------ | ------------ | ------------ | | 1 | VBAT | | | | | 3 | PC13 | | | | diff --git a/F1:F103/CDC_ACM/Makefile b/F1:F103/deprecated/CDC_ACM/Makefile similarity index 100% rename from F1:F103/CDC_ACM/Makefile rename to F1:F103/deprecated/CDC_ACM/Makefile diff --git a/F1:F103/CDC_ACM/Readme b/F1:F103/deprecated/CDC_ACM/Readme similarity index 100% rename from F1:F103/CDC_ACM/Readme rename to F1:F103/deprecated/CDC_ACM/Readme diff --git a/F1:F103/CDC_ACM/cdcacm.bin b/F1:F103/deprecated/CDC_ACM/cdcacm.bin similarity index 100% rename from F1:F103/CDC_ACM/cdcacm.bin rename to F1:F103/deprecated/CDC_ACM/cdcacm.bin diff --git a/F1:F103/CDC_ACM/hardware.c b/F1:F103/deprecated/CDC_ACM/hardware.c similarity index 100% rename from F1:F103/CDC_ACM/hardware.c rename to F1:F103/deprecated/CDC_ACM/hardware.c diff --git a/F1:F103/CDC_ACM/hardware.h b/F1:F103/deprecated/CDC_ACM/hardware.h similarity index 100% rename from F1:F103/CDC_ACM/hardware.h rename to F1:F103/deprecated/CDC_ACM/hardware.h diff --git a/F1:F103/CDC_ACM/main.c b/F1:F103/deprecated/CDC_ACM/main.c similarity index 100% rename from F1:F103/CDC_ACM/main.c rename to F1:F103/deprecated/CDC_ACM/main.c diff --git a/F1:F103/CDC_ACM/proto.c b/F1:F103/deprecated/CDC_ACM/proto.c similarity index 100% rename from F1:F103/CDC_ACM/proto.c rename to F1:F103/deprecated/CDC_ACM/proto.c diff --git a/F1:F103/CDC_ACM/proto.h b/F1:F103/deprecated/CDC_ACM/proto.h similarity index 100% rename from F1:F103/CDC_ACM/proto.h rename to F1:F103/deprecated/CDC_ACM/proto.h diff --git a/F1:F103/CDC_ACM/usb.c b/F1:F103/deprecated/CDC_ACM/usb.c similarity index 100% rename from F1:F103/CDC_ACM/usb.c rename to F1:F103/deprecated/CDC_ACM/usb.c diff --git a/F1:F103/CDC_ACM/usb.h b/F1:F103/deprecated/CDC_ACM/usb.h similarity index 100% rename from F1:F103/CDC_ACM/usb.h rename to F1:F103/deprecated/CDC_ACM/usb.h diff --git a/F1:F103/CDC_ACM/usb_defs.h b/F1:F103/deprecated/CDC_ACM/usb_defs.h similarity index 100% rename from F1:F103/CDC_ACM/usb_defs.h rename to F1:F103/deprecated/CDC_ACM/usb_defs.h diff --git a/F1:F103/CDC_ACM/usb_lib.c b/F1:F103/deprecated/CDC_ACM/usb_lib.c similarity index 100% rename from F1:F103/CDC_ACM/usb_lib.c rename to F1:F103/deprecated/CDC_ACM/usb_lib.c diff --git a/F1:F103/CDC_ACM/usb_lib.h b/F1:F103/deprecated/CDC_ACM/usb_lib.h similarity index 100% rename from F1:F103/CDC_ACM/usb_lib.h rename to F1:F103/deprecated/CDC_ACM/usb_lib.h diff --git a/F1:F103/MLX90640/MLX90640.bin b/F1:F103/deprecated/MLX90640/MLX90640.bin similarity index 100% rename from F1:F103/MLX90640/MLX90640.bin rename to F1:F103/deprecated/MLX90640/MLX90640.bin diff --git a/F1:F103/MLX90640/Makefile b/F1:F103/deprecated/MLX90640/Makefile similarity index 100% rename from F1:F103/MLX90640/Makefile rename to F1:F103/deprecated/MLX90640/Makefile diff --git a/F1:F103/MLX90640/Readme b/F1:F103/deprecated/MLX90640/Readme similarity index 100% rename from F1:F103/MLX90640/Readme rename to F1:F103/deprecated/MLX90640/Readme diff --git a/F1:F103/MLX90640/hardware.c b/F1:F103/deprecated/MLX90640/hardware.c similarity index 100% rename from F1:F103/MLX90640/hardware.c rename to F1:F103/deprecated/MLX90640/hardware.c diff --git a/F1:F103/MLX90640/hardware.h b/F1:F103/deprecated/MLX90640/hardware.h similarity index 100% rename from F1:F103/MLX90640/hardware.h rename to F1:F103/deprecated/MLX90640/hardware.h diff --git a/F1:F103/MLX90640/i2c.c b/F1:F103/deprecated/MLX90640/i2c.c similarity index 100% rename from F1:F103/MLX90640/i2c.c rename to F1:F103/deprecated/MLX90640/i2c.c diff --git a/F1:F103/MLX90640/i2c.h b/F1:F103/deprecated/MLX90640/i2c.h similarity index 100% rename from F1:F103/MLX90640/i2c.h rename to F1:F103/deprecated/MLX90640/i2c.h diff --git a/F1:F103/MLX90640/main.c b/F1:F103/deprecated/MLX90640/main.c similarity index 100% rename from F1:F103/MLX90640/main.c rename to F1:F103/deprecated/MLX90640/main.c diff --git a/F1:F103/MLX90640/mlx90640.c b/F1:F103/deprecated/MLX90640/mlx90640.c similarity index 100% rename from F1:F103/MLX90640/mlx90640.c rename to F1:F103/deprecated/MLX90640/mlx90640.c diff --git a/F1:F103/MLX90640/mlx90640.h b/F1:F103/deprecated/MLX90640/mlx90640.h similarity index 100% rename from F1:F103/MLX90640/mlx90640.h rename to F1:F103/deprecated/MLX90640/mlx90640.h diff --git a/F1:F103/MLX90640/mlx90640_regs.h b/F1:F103/deprecated/MLX90640/mlx90640_regs.h similarity index 100% rename from F1:F103/MLX90640/mlx90640_regs.h rename to F1:F103/deprecated/MLX90640/mlx90640_regs.h diff --git a/F1:F103/MLX90640/proto.c b/F1:F103/deprecated/MLX90640/proto.c similarity index 100% rename from F1:F103/MLX90640/proto.c rename to F1:F103/deprecated/MLX90640/proto.c diff --git a/F1:F103/MLX90640/proto.h b/F1:F103/deprecated/MLX90640/proto.h similarity index 100% rename from F1:F103/MLX90640/proto.h rename to F1:F103/deprecated/MLX90640/proto.h diff --git a/F1:F103/MLX90640/strfunct.c b/F1:F103/deprecated/MLX90640/strfunct.c similarity index 100% rename from F1:F103/MLX90640/strfunct.c rename to F1:F103/deprecated/MLX90640/strfunct.c diff --git a/F1:F103/MLX90640/strfunct.h b/F1:F103/deprecated/MLX90640/strfunct.h similarity index 100% rename from F1:F103/MLX90640/strfunct.h rename to F1:F103/deprecated/MLX90640/strfunct.h diff --git a/F1:F103/MLX90640/usb.c b/F1:F103/deprecated/MLX90640/usb.c similarity index 100% rename from F1:F103/MLX90640/usb.c rename to F1:F103/deprecated/MLX90640/usb.c diff --git a/F1:F103/MLX90640/usb.h b/F1:F103/deprecated/MLX90640/usb.h similarity index 100% rename from F1:F103/MLX90640/usb.h rename to F1:F103/deprecated/MLX90640/usb.h diff --git a/F1:F103/MLX90640/usb_defs.h b/F1:F103/deprecated/MLX90640/usb_defs.h similarity index 100% rename from F1:F103/MLX90640/usb_defs.h rename to F1:F103/deprecated/MLX90640/usb_defs.h diff --git a/F1:F103/MLX90640/usb_lib.c b/F1:F103/deprecated/MLX90640/usb_lib.c similarity index 100% rename from F1:F103/MLX90640/usb_lib.c rename to F1:F103/deprecated/MLX90640/usb_lib.c diff --git a/F1:F103/MLX90640/usb_lib.h b/F1:F103/deprecated/MLX90640/usb_lib.h similarity index 100% rename from F1:F103/MLX90640/usb_lib.h rename to F1:F103/deprecated/MLX90640/usb_lib.h diff --git a/F1:F103/MLX90640/version.inc b/F1:F103/deprecated/MLX90640/version.inc similarity index 100% rename from F1:F103/MLX90640/version.inc rename to F1:F103/deprecated/MLX90640/version.inc diff --git a/F1:F103/PL2303/Makefile b/F1:F103/deprecated/PL2303/Makefile similarity index 100% rename from F1:F103/PL2303/Makefile rename to F1:F103/deprecated/PL2303/Makefile diff --git a/F1:F103/PL2303/Readme b/F1:F103/deprecated/PL2303/Readme similarity index 100% rename from F1:F103/PL2303/Readme rename to F1:F103/deprecated/PL2303/Readme diff --git a/F1:F103/PL2303/hardware.c b/F1:F103/deprecated/PL2303/hardware.c similarity index 100% rename from F1:F103/PL2303/hardware.c rename to F1:F103/deprecated/PL2303/hardware.c diff --git a/F1:F103/PL2303/hardware.h b/F1:F103/deprecated/PL2303/hardware.h similarity index 100% rename from F1:F103/PL2303/hardware.h rename to F1:F103/deprecated/PL2303/hardware.h diff --git a/F1:F103/PL2303/main.c b/F1:F103/deprecated/PL2303/main.c similarity index 100% rename from F1:F103/PL2303/main.c rename to F1:F103/deprecated/PL2303/main.c diff --git a/F1:F103/PL2303/pl2303.bin b/F1:F103/deprecated/PL2303/pl2303.bin similarity index 100% rename from F1:F103/PL2303/pl2303.bin rename to F1:F103/deprecated/PL2303/pl2303.bin diff --git a/F1:F103/PL2303/usart.c b/F1:F103/deprecated/PL2303/usart.c similarity index 100% rename from F1:F103/PL2303/usart.c rename to F1:F103/deprecated/PL2303/usart.c diff --git a/F1:F103/PL2303/usart.h b/F1:F103/deprecated/PL2303/usart.h similarity index 100% rename from F1:F103/PL2303/usart.h rename to F1:F103/deprecated/PL2303/usart.h diff --git a/F1:F103/PL2303/usb.c b/F1:F103/deprecated/PL2303/usb.c similarity index 100% rename from F1:F103/PL2303/usb.c rename to F1:F103/deprecated/PL2303/usb.c diff --git a/F1:F103/PL2303/usb.h b/F1:F103/deprecated/PL2303/usb.h similarity index 100% rename from F1:F103/PL2303/usb.h rename to F1:F103/deprecated/PL2303/usb.h diff --git a/F1:F103/PL2303/usb_defs.h b/F1:F103/deprecated/PL2303/usb_defs.h similarity index 100% rename from F1:F103/PL2303/usb_defs.h rename to F1:F103/deprecated/PL2303/usb_defs.h diff --git a/F1:F103/PL2303/usb_lib.c b/F1:F103/deprecated/PL2303/usb_lib.c similarity index 100% rename from F1:F103/PL2303/usb_lib.c rename to F1:F103/deprecated/PL2303/usb_lib.c diff --git a/F1:F103/PL2303/usb_lib.h b/F1:F103/deprecated/PL2303/usb_lib.h similarity index 100% rename from F1:F103/PL2303/usb_lib.h rename to F1:F103/deprecated/PL2303/usb_lib.h diff --git a/F1:F103/deprecated/Readme.md b/F1:F103/deprecated/Readme.md new file mode 100644 index 0000000..b95949a --- /dev/null +++ b/F1:F103/deprecated/Readme.md @@ -0,0 +1,7 @@ +- **CDC_ACM** - simplest CDC-ACM snippet (*deprecated*) +- **chronometer** - first version of chronometer for bike/auto/moto competitions +- **chronometer_v2** - chrono-2 +- **MLX90640** - test of MLX90640 (*deprecated* as can't calculate so many sqrt's on STM32F103) +- **PL2303** - based PL2303 emulation (*deprecated*) +- **pl2303_snippet** - (*deprecated*) +- **pl2303_snippet_naked** - (*deprecated*) diff --git a/F1:F103/chronometer/GPS.c b/F1:F103/deprecated/chronometer/GPS.c similarity index 100% rename from F1:F103/chronometer/GPS.c rename to F1:F103/deprecated/chronometer/GPS.c diff --git a/F1:F103/chronometer/GPS.h b/F1:F103/deprecated/chronometer/GPS.h similarity index 100% rename from F1:F103/chronometer/GPS.h rename to F1:F103/deprecated/chronometer/GPS.h diff --git a/F1:F103/chronometer/Makefile b/F1:F103/deprecated/chronometer/Makefile similarity index 100% rename from F1:F103/chronometer/Makefile rename to F1:F103/deprecated/chronometer/Makefile diff --git a/F1:F103/chronometer/Readme.md b/F1:F103/deprecated/chronometer/Readme.md similarity index 100% rename from F1:F103/chronometer/Readme.md rename to F1:F103/deprecated/chronometer/Readme.md diff --git a/F1:F103/chronometer/Readme_rus.txt b/F1:F103/deprecated/chronometer/Readme_rus.txt similarity index 100% rename from F1:F103/chronometer/Readme_rus.txt rename to F1:F103/deprecated/chronometer/Readme_rus.txt diff --git a/F1:F103/chronometer/adc.c b/F1:F103/deprecated/chronometer/adc.c similarity index 100% rename from F1:F103/chronometer/adc.c rename to F1:F103/deprecated/chronometer/adc.c diff --git a/F1:F103/chronometer/adc.h b/F1:F103/deprecated/chronometer/adc.h similarity index 100% rename from F1:F103/chronometer/adc.h rename to F1:F103/deprecated/chronometer/adc.h diff --git a/F1:F103/chronometer/chrono.bin b/F1:F103/deprecated/chronometer/chrono.bin similarity index 100% rename from F1:F103/chronometer/chrono.bin rename to F1:F103/deprecated/chronometer/chrono.bin diff --git a/F1:F103/chronometer/flash.c b/F1:F103/deprecated/chronometer/flash.c similarity index 100% rename from F1:F103/chronometer/flash.c rename to F1:F103/deprecated/chronometer/flash.c diff --git a/F1:F103/chronometer/flash.h b/F1:F103/deprecated/chronometer/flash.h similarity index 100% rename from F1:F103/chronometer/flash.h rename to F1:F103/deprecated/chronometer/flash.h diff --git a/F1:F103/chronometer/hardware.c b/F1:F103/deprecated/chronometer/hardware.c similarity index 100% rename from F1:F103/chronometer/hardware.c rename to F1:F103/deprecated/chronometer/hardware.c diff --git a/F1:F103/chronometer/hardware.h b/F1:F103/deprecated/chronometer/hardware.h similarity index 100% rename from F1:F103/chronometer/hardware.h rename to F1:F103/deprecated/chronometer/hardware.h diff --git a/F1:F103/chronometer/lidar.c b/F1:F103/deprecated/chronometer/lidar.c similarity index 100% rename from F1:F103/chronometer/lidar.c rename to F1:F103/deprecated/chronometer/lidar.c diff --git a/F1:F103/chronometer/lidar.h b/F1:F103/deprecated/chronometer/lidar.h similarity index 100% rename from F1:F103/chronometer/lidar.h rename to F1:F103/deprecated/chronometer/lidar.h diff --git a/F1:F103/chronometer/main.c b/F1:F103/deprecated/chronometer/main.c similarity index 100% rename from F1:F103/chronometer/main.c rename to F1:F103/deprecated/chronometer/main.c diff --git a/F1:F103/chronometer/stm32F103xB.ld b/F1:F103/deprecated/chronometer/stm32F103xB.ld similarity index 100% rename from F1:F103/chronometer/stm32F103xB.ld rename to F1:F103/deprecated/chronometer/stm32F103xB.ld diff --git a/F1:F103/chronometer/str.c b/F1:F103/deprecated/chronometer/str.c similarity index 100% rename from F1:F103/chronometer/str.c rename to F1:F103/deprecated/chronometer/str.c diff --git a/F1:F103/chronometer/str.h b/F1:F103/deprecated/chronometer/str.h similarity index 100% rename from F1:F103/chronometer/str.h rename to F1:F103/deprecated/chronometer/str.h diff --git a/F1:F103/chronometer/time.c b/F1:F103/deprecated/chronometer/time.c similarity index 100% rename from F1:F103/chronometer/time.c rename to F1:F103/deprecated/chronometer/time.c diff --git a/F1:F103/chronometer/time.h b/F1:F103/deprecated/chronometer/time.h similarity index 100% rename from F1:F103/chronometer/time.h rename to F1:F103/deprecated/chronometer/time.h diff --git a/F1:F103/chronometer/usart.c b/F1:F103/deprecated/chronometer/usart.c similarity index 100% rename from F1:F103/chronometer/usart.c rename to F1:F103/deprecated/chronometer/usart.c diff --git a/F1:F103/chronometer/usart.h b/F1:F103/deprecated/chronometer/usart.h similarity index 100% rename from F1:F103/chronometer/usart.h rename to F1:F103/deprecated/chronometer/usart.h diff --git a/F1:F103/chronometer/usb.c b/F1:F103/deprecated/chronometer/usb.c similarity index 100% rename from F1:F103/chronometer/usb.c rename to F1:F103/deprecated/chronometer/usb.c diff --git a/F1:F103/chronometer/usb.h b/F1:F103/deprecated/chronometer/usb.h similarity index 100% rename from F1:F103/chronometer/usb.h rename to F1:F103/deprecated/chronometer/usb.h diff --git a/F1:F103/chronometer/usb_defs.h b/F1:F103/deprecated/chronometer/usb_defs.h similarity index 100% rename from F1:F103/chronometer/usb_defs.h rename to F1:F103/deprecated/chronometer/usb_defs.h diff --git a/F1:F103/chronometer/usb_lib.c b/F1:F103/deprecated/chronometer/usb_lib.c similarity index 100% rename from F1:F103/chronometer/usb_lib.c rename to F1:F103/deprecated/chronometer/usb_lib.c diff --git a/F1:F103/chronometer/usb_lib.h b/F1:F103/deprecated/chronometer/usb_lib.h similarity index 100% rename from F1:F103/chronometer/usb_lib.h rename to F1:F103/deprecated/chronometer/usb_lib.h diff --git a/F1:F103/chronometer_v2/Difference b/F1:F103/deprecated/chronometer_v2/Difference similarity index 100% rename from F1:F103/chronometer_v2/Difference rename to F1:F103/deprecated/chronometer_v2/Difference diff --git a/F1:F103/chronometer_v2/GPS.c b/F1:F103/deprecated/chronometer_v2/GPS.c similarity index 100% rename from F1:F103/chronometer_v2/GPS.c rename to F1:F103/deprecated/chronometer_v2/GPS.c diff --git a/F1:F103/chronometer_v2/GPS.h b/F1:F103/deprecated/chronometer_v2/GPS.h similarity index 100% rename from F1:F103/chronometer_v2/GPS.h rename to F1:F103/deprecated/chronometer_v2/GPS.h diff --git a/F1:F103/chronometer_v2/Makefile b/F1:F103/deprecated/chronometer_v2/Makefile similarity index 100% rename from F1:F103/chronometer_v2/Makefile rename to F1:F103/deprecated/chronometer_v2/Makefile diff --git a/F1:F103/chronometer_v2/Readme.md b/F1:F103/deprecated/chronometer_v2/Readme.md similarity index 100% rename from F1:F103/chronometer_v2/Readme.md rename to F1:F103/deprecated/chronometer_v2/Readme.md diff --git a/F1:F103/chronometer_v2/Readme_rus.txt b/F1:F103/deprecated/chronometer_v2/Readme_rus.txt similarity index 100% rename from F1:F103/chronometer_v2/Readme_rus.txt rename to F1:F103/deprecated/chronometer_v2/Readme_rus.txt diff --git a/F1:F103/chronometer_v2/adc.c b/F1:F103/deprecated/chronometer_v2/adc.c similarity index 100% rename from F1:F103/chronometer_v2/adc.c rename to F1:F103/deprecated/chronometer_v2/adc.c diff --git a/F1:F103/chronometer_v2/adc.h b/F1:F103/deprecated/chronometer_v2/adc.h similarity index 100% rename from F1:F103/chronometer_v2/adc.h rename to F1:F103/deprecated/chronometer_v2/adc.h diff --git a/F1:F103/chronometer_v2/chrono.bin b/F1:F103/deprecated/chronometer_v2/chrono.bin similarity index 100% rename from F1:F103/chronometer_v2/chrono.bin rename to F1:F103/deprecated/chronometer_v2/chrono.bin diff --git a/F1:F103/chronometer_v2/flash.c b/F1:F103/deprecated/chronometer_v2/flash.c similarity index 100% rename from F1:F103/chronometer_v2/flash.c rename to F1:F103/deprecated/chronometer_v2/flash.c diff --git a/F1:F103/chronometer_v2/flash.h b/F1:F103/deprecated/chronometer_v2/flash.h similarity index 100% rename from F1:F103/chronometer_v2/flash.h rename to F1:F103/deprecated/chronometer_v2/flash.h diff --git a/F1:F103/chronometer_v2/hardware.c b/F1:F103/deprecated/chronometer_v2/hardware.c similarity index 100% rename from F1:F103/chronometer_v2/hardware.c rename to F1:F103/deprecated/chronometer_v2/hardware.c diff --git a/F1:F103/chronometer_v2/hardware.h b/F1:F103/deprecated/chronometer_v2/hardware.h similarity index 100% rename from F1:F103/chronometer_v2/hardware.h rename to F1:F103/deprecated/chronometer_v2/hardware.h diff --git a/F1:F103/chronometer_v2/kicad/2019.10.23-22:09:24.png b/F1:F103/deprecated/chronometer_v2/kicad/2019.10.23-22:09:24.png similarity index 100% rename from F1:F103/chronometer_v2/kicad/2019.10.23-22:09:24.png rename to F1:F103/deprecated/chronometer_v2/kicad/2019.10.23-22:09:24.png diff --git a/F1:F103/chronometer_v2/kicad/2019.10.23_22:08:42.png b/F1:F103/deprecated/chronometer_v2/kicad/2019.10.23_22:08:42.png similarity index 100% rename from F1:F103/chronometer_v2/kicad/2019.10.23_22:08:42.png rename to F1:F103/deprecated/chronometer_v2/kicad/2019.10.23_22:08:42.png diff --git a/F1:F103/chronometer_v2/kicad/Chrono.lib b/F1:F103/deprecated/chronometer_v2/kicad/Chrono.lib similarity index 100% rename from F1:F103/chronometer_v2/kicad/Chrono.lib rename to F1:F103/deprecated/chronometer_v2/kicad/Chrono.lib diff --git a/F1:F103/chronometer_v2/kicad/chrono b/F1:F103/deprecated/chronometer_v2/kicad/chrono similarity index 100% rename from F1:F103/chronometer_v2/kicad/chrono rename to F1:F103/deprecated/chronometer_v2/kicad/chrono diff --git a/F1:F103/chronometer_v2/kicad/chrono.kicad_pcb b/F1:F103/deprecated/chronometer_v2/kicad/chrono.kicad_pcb similarity index 100% rename from F1:F103/chronometer_v2/kicad/chrono.kicad_pcb rename to F1:F103/deprecated/chronometer_v2/kicad/chrono.kicad_pcb diff --git a/F1:F103/chronometer_v2/kicad/chrono.kicad_prl b/F1:F103/deprecated/chronometer_v2/kicad/chrono.kicad_prl similarity index 100% rename from F1:F103/chronometer_v2/kicad/chrono.kicad_prl rename to F1:F103/deprecated/chronometer_v2/kicad/chrono.kicad_prl diff --git a/F1:F103/chronometer_v2/kicad/chrono.kicad_pro b/F1:F103/deprecated/chronometer_v2/kicad/chrono.kicad_pro similarity index 100% rename from F1:F103/chronometer_v2/kicad/chrono.kicad_pro rename to F1:F103/deprecated/chronometer_v2/kicad/chrono.kicad_pro diff --git a/F1:F103/chronometer_v2/kicad/chrono.kicad_sch b/F1:F103/deprecated/chronometer_v2/kicad/chrono.kicad_sch similarity index 100% rename from F1:F103/chronometer_v2/kicad/chrono.kicad_sch rename to F1:F103/deprecated/chronometer_v2/kicad/chrono.kicad_sch diff --git a/F1:F103/chronometer_v2/kicad/chrono.net b/F1:F103/deprecated/chronometer_v2/kicad/chrono.net similarity index 100% rename from F1:F103/chronometer_v2/kicad/chrono.net rename to F1:F103/deprecated/chronometer_v2/kicad/chrono.net diff --git a/F1:F103/chronometer_v2/kicad/chrono.pretty/L80-R.kicad_mod b/F1:F103/deprecated/chronometer_v2/kicad/chrono.pretty/L80-R.kicad_mod similarity index 100% rename from F1:F103/chronometer_v2/kicad/chrono.pretty/L80-R.kicad_mod rename to F1:F103/deprecated/chronometer_v2/kicad/chrono.pretty/L80-R.kicad_mod diff --git a/F1:F103/chronometer_v2/kicad/chrono.pro b/F1:F103/deprecated/chronometer_v2/kicad/chrono.pro similarity index 100% rename from F1:F103/chronometer_v2/kicad/chrono.pro rename to F1:F103/deprecated/chronometer_v2/kicad/chrono.pro diff --git a/F1:F103/chronometer_v2/kicad/chrono.sch b/F1:F103/deprecated/chronometer_v2/kicad/chrono.sch similarity index 100% rename from F1:F103/chronometer_v2/kicad/chrono.sch rename to F1:F103/deprecated/chronometer_v2/kicad/chrono.sch diff --git a/F1:F103/chronometer_v2/kicad/fp-info-cache b/F1:F103/deprecated/chronometer_v2/kicad/fp-info-cache similarity index 100% rename from F1:F103/chronometer_v2/kicad/fp-info-cache rename to F1:F103/deprecated/chronometer_v2/kicad/fp-info-cache diff --git a/F1:F103/chronometer_v2/kicad/fp-lib-table b/F1:F103/deprecated/chronometer_v2/kicad/fp-lib-table similarity index 100% rename from F1:F103/chronometer_v2/kicad/fp-lib-table rename to F1:F103/deprecated/chronometer_v2/kicad/fp-lib-table diff --git a/F1:F103/chronometer_v2/kicad/gerbers/chrono-B_Cu.gbr b/F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-B_Cu.gbr similarity index 100% rename from F1:F103/chronometer_v2/kicad/gerbers/chrono-B_Cu.gbr rename to F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-B_Cu.gbr diff --git a/F1:F103/chronometer_v2/kicad/gerbers/chrono-B_Mask.gbr b/F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-B_Mask.gbr similarity index 100% rename from F1:F103/chronometer_v2/kicad/gerbers/chrono-B_Mask.gbr rename to F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-B_Mask.gbr diff --git a/F1:F103/chronometer_v2/kicad/gerbers/chrono-B_SilkS.gbr b/F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-B_SilkS.gbr similarity index 100% rename from F1:F103/chronometer_v2/kicad/gerbers/chrono-B_SilkS.gbr rename to F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-B_SilkS.gbr diff --git a/F1:F103/chronometer_v2/kicad/gerbers/chrono-Edge_Cuts.gbr b/F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-Edge_Cuts.gbr similarity index 100% rename from F1:F103/chronometer_v2/kicad/gerbers/chrono-Edge_Cuts.gbr rename to F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-Edge_Cuts.gbr diff --git a/F1:F103/chronometer_v2/kicad/gerbers/chrono-F_Cu.gbr b/F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-F_Cu.gbr similarity index 100% rename from F1:F103/chronometer_v2/kicad/gerbers/chrono-F_Cu.gbr rename to F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-F_Cu.gbr diff --git a/F1:F103/chronometer_v2/kicad/gerbers/chrono-F_Mask.gbr b/F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-F_Mask.gbr similarity index 100% rename from F1:F103/chronometer_v2/kicad/gerbers/chrono-F_Mask.gbr rename to F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-F_Mask.gbr diff --git a/F1:F103/chronometer_v2/kicad/gerbers/chrono-F_SilkS.gbr b/F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-F_SilkS.gbr similarity index 100% rename from F1:F103/chronometer_v2/kicad/gerbers/chrono-F_SilkS.gbr rename to F1:F103/deprecated/chronometer_v2/kicad/gerbers/chrono-F_SilkS.gbr diff --git a/F1:F103/chronometer_v2/kicad/stm32-rescue.lib b/F1:F103/deprecated/chronometer_v2/kicad/stm32-rescue.lib similarity index 100% rename from F1:F103/chronometer_v2/kicad/stm32-rescue.lib rename to F1:F103/deprecated/chronometer_v2/kicad/stm32-rescue.lib diff --git a/F1:F103/chronometer_v2/kicad/sym-lib-table b/F1:F103/deprecated/chronometer_v2/kicad/sym-lib-table similarity index 100% rename from F1:F103/chronometer_v2/kicad/sym-lib-table rename to F1:F103/deprecated/chronometer_v2/kicad/sym-lib-table diff --git a/F1:F103/chronometer_v2/lidar.c b/F1:F103/deprecated/chronometer_v2/lidar.c similarity index 100% rename from F1:F103/chronometer_v2/lidar.c rename to F1:F103/deprecated/chronometer_v2/lidar.c diff --git a/F1:F103/chronometer_v2/lidar.h b/F1:F103/deprecated/chronometer_v2/lidar.h similarity index 100% rename from F1:F103/chronometer_v2/lidar.h rename to F1:F103/deprecated/chronometer_v2/lidar.h diff --git a/F1:F103/chronometer_v2/main.c b/F1:F103/deprecated/chronometer_v2/main.c similarity index 100% rename from F1:F103/chronometer_v2/main.c rename to F1:F103/deprecated/chronometer_v2/main.c diff --git a/F1:F103/chronometer_v2/stm32F103xB.ld b/F1:F103/deprecated/chronometer_v2/stm32F103xB.ld similarity index 100% rename from F1:F103/chronometer_v2/stm32F103xB.ld rename to F1:F103/deprecated/chronometer_v2/stm32F103xB.ld diff --git a/F1:F103/chronometer_v2/str.c b/F1:F103/deprecated/chronometer_v2/str.c similarity index 100% rename from F1:F103/chronometer_v2/str.c rename to F1:F103/deprecated/chronometer_v2/str.c diff --git a/F1:F103/chronometer_v2/str.h b/F1:F103/deprecated/chronometer_v2/str.h similarity index 100% rename from F1:F103/chronometer_v2/str.h rename to F1:F103/deprecated/chronometer_v2/str.h diff --git a/F1:F103/chronometer_v2/time.c b/F1:F103/deprecated/chronometer_v2/time.c similarity index 100% rename from F1:F103/chronometer_v2/time.c rename to F1:F103/deprecated/chronometer_v2/time.c diff --git a/F1:F103/chronometer_v2/time.h b/F1:F103/deprecated/chronometer_v2/time.h similarity index 100% rename from F1:F103/chronometer_v2/time.h rename to F1:F103/deprecated/chronometer_v2/time.h diff --git a/F1:F103/chronometer_v2/usart.c b/F1:F103/deprecated/chronometer_v2/usart.c similarity index 100% rename from F1:F103/chronometer_v2/usart.c rename to F1:F103/deprecated/chronometer_v2/usart.c diff --git a/F1:F103/chronometer_v2/usart.h b/F1:F103/deprecated/chronometer_v2/usart.h similarity index 100% rename from F1:F103/chronometer_v2/usart.h rename to F1:F103/deprecated/chronometer_v2/usart.h diff --git a/F1:F103/chronometer_v2/usb.c b/F1:F103/deprecated/chronometer_v2/usb.c similarity index 100% rename from F1:F103/chronometer_v2/usb.c rename to F1:F103/deprecated/chronometer_v2/usb.c diff --git a/F1:F103/chronometer_v2/usb.h b/F1:F103/deprecated/chronometer_v2/usb.h similarity index 100% rename from F1:F103/chronometer_v2/usb.h rename to F1:F103/deprecated/chronometer_v2/usb.h diff --git a/F1:F103/chronometer_v2/usb_defs.h b/F1:F103/deprecated/chronometer_v2/usb_defs.h similarity index 100% rename from F1:F103/chronometer_v2/usb_defs.h rename to F1:F103/deprecated/chronometer_v2/usb_defs.h diff --git a/F1:F103/chronometer_v2/usb_lib.c b/F1:F103/deprecated/chronometer_v2/usb_lib.c similarity index 100% rename from F1:F103/chronometer_v2/usb_lib.c rename to F1:F103/deprecated/chronometer_v2/usb_lib.c diff --git a/F1:F103/chronometer_v2/usb_lib.h b/F1:F103/deprecated/chronometer_v2/usb_lib.h similarity index 100% rename from F1:F103/chronometer_v2/usb_lib.h rename to F1:F103/deprecated/chronometer_v2/usb_lib.h diff --git a/F1:F103/pl2303_snippet/Makefile b/F1:F103/deprecated/pl2303_snippet/Makefile similarity index 100% rename from F1:F103/pl2303_snippet/Makefile rename to F1:F103/deprecated/pl2303_snippet/Makefile diff --git a/F1:F103/pl2303_snippet/Readme b/F1:F103/deprecated/pl2303_snippet/Readme similarity index 100% rename from F1:F103/pl2303_snippet/Readme rename to F1:F103/deprecated/pl2303_snippet/Readme diff --git a/F1:F103/pl2303_snippet/hardware.c b/F1:F103/deprecated/pl2303_snippet/hardware.c similarity index 100% rename from F1:F103/pl2303_snippet/hardware.c rename to F1:F103/deprecated/pl2303_snippet/hardware.c diff --git a/F1:F103/pl2303_snippet/hardware.h b/F1:F103/deprecated/pl2303_snippet/hardware.h similarity index 100% rename from F1:F103/pl2303_snippet/hardware.h rename to F1:F103/deprecated/pl2303_snippet/hardware.h diff --git a/F1:F103/pl2303_snippet/main.c b/F1:F103/deprecated/pl2303_snippet/main.c similarity index 100% rename from F1:F103/pl2303_snippet/main.c rename to F1:F103/deprecated/pl2303_snippet/main.c diff --git a/F1:F103/pl2303_snippet/pl2303.bin b/F1:F103/deprecated/pl2303_snippet/pl2303.bin similarity index 100% rename from F1:F103/pl2303_snippet/pl2303.bin rename to F1:F103/deprecated/pl2303_snippet/pl2303.bin diff --git a/F1:F103/pl2303_snippet/proto.c b/F1:F103/deprecated/pl2303_snippet/proto.c similarity index 100% rename from F1:F103/pl2303_snippet/proto.c rename to F1:F103/deprecated/pl2303_snippet/proto.c diff --git a/F1:F103/pl2303_snippet/proto.h b/F1:F103/deprecated/pl2303_snippet/proto.h similarity index 100% rename from F1:F103/pl2303_snippet/proto.h rename to F1:F103/deprecated/pl2303_snippet/proto.h diff --git a/F1:F103/pl2303_snippet/usb.c b/F1:F103/deprecated/pl2303_snippet/usb.c similarity index 100% rename from F1:F103/pl2303_snippet/usb.c rename to F1:F103/deprecated/pl2303_snippet/usb.c diff --git a/F1:F103/pl2303_snippet/usb.h b/F1:F103/deprecated/pl2303_snippet/usb.h similarity index 100% rename from F1:F103/pl2303_snippet/usb.h rename to F1:F103/deprecated/pl2303_snippet/usb.h diff --git a/F1:F103/pl2303_snippet/usb_defs.h b/F1:F103/deprecated/pl2303_snippet/usb_defs.h similarity index 100% rename from F1:F103/pl2303_snippet/usb_defs.h rename to F1:F103/deprecated/pl2303_snippet/usb_defs.h diff --git a/F1:F103/pl2303_snippet/usb_lib.c b/F1:F103/deprecated/pl2303_snippet/usb_lib.c similarity index 100% rename from F1:F103/pl2303_snippet/usb_lib.c rename to F1:F103/deprecated/pl2303_snippet/usb_lib.c diff --git a/F1:F103/pl2303_snippet/usb_lib.h b/F1:F103/deprecated/pl2303_snippet/usb_lib.h similarity index 100% rename from F1:F103/pl2303_snippet/usb_lib.h rename to F1:F103/deprecated/pl2303_snippet/usb_lib.h diff --git a/F1:F103/pl2303_snippet_naked/Makefile b/F1:F103/deprecated/pl2303_snippet_naked/Makefile similarity index 100% rename from F1:F103/pl2303_snippet_naked/Makefile rename to F1:F103/deprecated/pl2303_snippet_naked/Makefile diff --git a/F1:F103/pl2303_snippet_naked/Readme b/F1:F103/deprecated/pl2303_snippet_naked/Readme similarity index 100% rename from F1:F103/pl2303_snippet_naked/Readme rename to F1:F103/deprecated/pl2303_snippet_naked/Readme diff --git a/F1:F103/pl2303_snippet_naked/hardware.c b/F1:F103/deprecated/pl2303_snippet_naked/hardware.c similarity index 100% rename from F1:F103/pl2303_snippet_naked/hardware.c rename to F1:F103/deprecated/pl2303_snippet_naked/hardware.c diff --git a/F1:F103/pl2303_snippet_naked/hardware.h b/F1:F103/deprecated/pl2303_snippet_naked/hardware.h similarity index 100% rename from F1:F103/pl2303_snippet_naked/hardware.h rename to F1:F103/deprecated/pl2303_snippet_naked/hardware.h diff --git a/F1:F103/pl2303_snippet_naked/main.c b/F1:F103/deprecated/pl2303_snippet_naked/main.c similarity index 100% rename from F1:F103/pl2303_snippet_naked/main.c rename to F1:F103/deprecated/pl2303_snippet_naked/main.c diff --git a/F1:F103/pl2303_snippet_naked/pl2303.bin b/F1:F103/deprecated/pl2303_snippet_naked/pl2303.bin similarity index 100% rename from F1:F103/pl2303_snippet_naked/pl2303.bin rename to F1:F103/deprecated/pl2303_snippet_naked/pl2303.bin diff --git a/F1:F103/pl2303_snippet_naked/proto.c b/F1:F103/deprecated/pl2303_snippet_naked/proto.c similarity index 100% rename from F1:F103/pl2303_snippet_naked/proto.c rename to F1:F103/deprecated/pl2303_snippet_naked/proto.c diff --git a/F1:F103/pl2303_snippet_naked/proto.h b/F1:F103/deprecated/pl2303_snippet_naked/proto.h similarity index 100% rename from F1:F103/pl2303_snippet_naked/proto.h rename to F1:F103/deprecated/pl2303_snippet_naked/proto.h diff --git a/F1:F103/pl2303_snippet_naked/usb.c b/F1:F103/deprecated/pl2303_snippet_naked/usb.c similarity index 100% rename from F1:F103/pl2303_snippet_naked/usb.c rename to F1:F103/deprecated/pl2303_snippet_naked/usb.c diff --git a/F1:F103/pl2303_snippet_naked/usb.h b/F1:F103/deprecated/pl2303_snippet_naked/usb.h similarity index 100% rename from F1:F103/pl2303_snippet_naked/usb.h rename to F1:F103/deprecated/pl2303_snippet_naked/usb.h diff --git a/F1:F103/pl2303_snippet_naked/usb_defs.h b/F1:F103/deprecated/pl2303_snippet_naked/usb_defs.h similarity index 100% rename from F1:F103/pl2303_snippet_naked/usb_defs.h rename to F1:F103/deprecated/pl2303_snippet_naked/usb_defs.h diff --git a/F1:F103/pl2303_snippet_naked/usb_lib.c b/F1:F103/deprecated/pl2303_snippet_naked/usb_lib.c similarity index 100% rename from F1:F103/pl2303_snippet_naked/usb_lib.c rename to F1:F103/deprecated/pl2303_snippet_naked/usb_lib.c diff --git a/F1:F103/pl2303_snippet_naked/usb_lib.h b/F1:F103/deprecated/pl2303_snippet_naked/usb_lib.h similarity index 100% rename from F1:F103/pl2303_snippet_naked/usb_lib.h rename to F1:F103/deprecated/pl2303_snippet_naked/usb_lib.h diff --git a/F3:F303/Multistepper/multistepper.bin b/F3:F303/Multistepper/multistepper.bin index 3c309ec64e23a596eef5376da2f2628e9b079885..8b131fb9733fd517807dfd9c05878c7d46a49781 100755 GIT binary patch delta 6920 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 delta 6928 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 p9k>MC0w`eI2VGzU`RV - + EnvironmentId diff --git a/F3:F303/Multistepper/ringbuffer.c b/F3:F303/Multistepper/ringbuffer.c index 7f78f8c..8d8d6ca 100644 --- a/F3:F303/Multistepper/ringbuffer.c +++ b/F3:F303/Multistepper/ringbuffer.c @@ -1,5 +1,4 @@ /* - * This file is part of the multistepper project. * Copyright 2023 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify diff --git a/F3:F303/Multistepper/ringbuffer.h b/F3:F303/Multistepper/ringbuffer.h index 549b5c0..ed2cf95 100644 --- a/F3:F303/Multistepper/ringbuffer.h +++ b/F3:F303/Multistepper/ringbuffer.h @@ -1,5 +1,4 @@ /* - * This file is part of the multistepper project. * Copyright 2023 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify @@ -18,7 +17,13 @@ #pragma once +#if defined STM32F0 +#include +#elif defined STM32F1 +#include +#elif defined STM32F3 #include +#endif typedef struct{ uint8_t *data; // data buffer diff --git a/F3:F303/Multistepper/usb.c b/F3:F303/Multistepper/usb.c index 313e723..a2ee479 100644 --- a/F3:F303/Multistepper/usb.c +++ b/F3:F303/Multistepper/usb.c @@ -1,5 +1,4 @@ /* - * This file is part of the multistepper project. * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify @@ -21,9 +20,6 @@ #include "hardware.h" #include "usb.h" #include "usb_lib.h" -#ifdef EBUG -#include "strfunc.h" -#endif static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data // ring buffers for incoming and outgoing data @@ -43,7 +39,9 @@ void send_next(){ lastdsz = 0; return; }else if(buflen < 0){ - EP_Write(3, NULL, 0); // send ZLP if buffer is in writting state now + lastdsz = 0; + // Uncomment next line if you want 4Mbit/s instead of 6Mbit/s + //EP_Write(3, NULL, 0); // send ZLP if buffer is in writting state now return; } EP_Write(3, (uint8_t*)usbbuff, buflen); @@ -130,9 +128,6 @@ int USB_receivestr(char *buf, int len){ } return 0; } -#ifdef EBUG - USB_sendstr("readto, l="); USB_sendstr(u2str(l)); newline(); -#endif if(l == 0) return 0; buf[l-1] = 0; // replace '\n' with strend return l; diff --git a/F3:F303/Multistepper/usb.h b/F3:F303/Multistepper/usb.h index cd2808e..4583b9b 100644 --- a/F3:F303/Multistepper/usb.h +++ b/F3:F303/Multistepper/usb.h @@ -1,5 +1,4 @@ /* - * This file is part of the multistepper project. * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify diff --git a/F3:F303/Multistepper/usb_lib.c b/F3:F303/Multistepper/usb_lib.c index 3ced8ec..aea5344 100644 --- a/F3:F303/Multistepper/usb_lib.c +++ b/F3:F303/Multistepper/usb_lib.c @@ -1,5 +1,4 @@ /* - * This file is part of the multistepper project. * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify @@ -15,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include #include "usb.h" #include "usb_lib.h" @@ -131,7 +129,7 @@ _USB_LANG_ID_(LD, LANG_US); _USB_STRING_(SD, u"0.0.1"); _USB_STRING_(MD, u"Prolific Technology Inc."); _USB_STRING_(PD, u"USB-Serial Controller"); -_USB_STRING_(ID, u"multistepper"); +_USB_STRING_(ID, u"USB-STM32"); static void const *StringDescriptor[iDESCR_AMOUNT] = { [iLANGUAGE_DESCR] = &LD, [iMANUFACTURER_DESCR] = &MD, @@ -266,13 +264,13 @@ static void transmit_Handler(){ // EP3IN send_next(); } -static uint8_t rcvbuf[USB_RXBUFSZ]; +static uint8_t volatile rcvbuf[USB_RXBUFSZ]; static uint8_t volatile rcvbuflen = 0; void chkin(){ if(bufovrfl) return; if(!rcvbuflen) return; - int w = RB_write((ringbuffer*)&rbin, rcvbuf, rcvbuflen); + int w = RB_write((ringbuffer*)&rbin, (uint8_t*)rcvbuf, rcvbuflen); if(w < 0) return; if(w != rcvbuflen) bufovrfl = 1; rcvbuflen = 0; @@ -450,3 +448,103 @@ int EP_Read(uint8_t number, uint8_t *buf){ return sz; } + +static uint16_t lastaddr = LASTADDR_DEFAULT; +/** + * Endpoint initialisation + * @param number - EP num (0...7) + * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) + * @param txsz - transmission buffer size @ USB/CAN buffer + * @param rxsz - reception buffer size @ USB/CAN buffer + * @param uint16_t (*func)(ep_t *ep) - EP handler function + * @return 0 if all OK + */ +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ + if(number >= STM32ENDPOINTS) return 4; // out of configured amount + if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large + if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE/ACCESSZ) return 2; // out of btable + USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); + USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; + if(rxsz & 1 || rxsz > USB_BTABLE_SIZE) return 3; // wrong rx buffer size + uint16_t countrx = 0; + if(rxsz < 64) countrx = rxsz / 2; + else{ + if(rxsz & 0x1f) return 3; // should be multiple of 32 + countrx = 31 + rxsz / 32; + } + USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; + endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + endpoints[number].txbufsz = txsz; + lastaddr += txsz; + USB_BTABLE->EP[number].USB_COUNT_TX = 0; + USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; + endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + lastaddr += rxsz; + USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; + endpoints[number].func = func; + return 0; +} + +// standard IRQ handler +void USB_IRQ(){ + if(USB->ISTR & USB_ISTR_RESET){ + usbON = 0; + // Reinit registers + USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + // Endpoint 0 - CONTROL + // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! + lastaddr = LASTADDR_DEFAULT; + // clear address, leave only enable bit + USB->DADDR = USB_DADDR_EF; + if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ + return; + } + USB->ISTR = ~USB_ISTR_RESET; + } + if(USB->ISTR & USB_ISTR_CTR){ + // EP number + uint8_t n = USB->ISTR & USB_ISTR_EPID; + // copy status register + uint16_t epstatus = USB->EPnR[n]; + // copy received bytes amount + endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter + // check direction + if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) + if(n == 0){ // control endpoint + if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack + EP_Read(0, setupdatabuf); + // interrupt handler will be called later + }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf + EP_Read(0, ep0databuf); + } + } + } + // call EP handler + if(endpoints[n].func) endpoints[n].func(endpoints[n]); + } + if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep + usbON = 0; +#ifndef STM32F0 + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; +#else + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LPMODE; +#endif + USB->ISTR = ~USB_ISTR_SUSP; + } + if(USB->ISTR & USB_ISTR_WKUP){ // wakeup +#ifndef STM32F0 + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags +#else + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LPMODE); +#endif + USB->ISTR = ~USB_ISTR_WKUP; + } +} + +#if defined STM32F3 +void usb_lp_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F1 +void usb_lp_can_rx0_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F0 +void usb_isr() __attribute__ ((alias ("USB_IRQ"))); +#endif diff --git a/F3:F303/Multistepper/usb_lib.h b/F3:F303/Multistepper/usb_lib.h index f35917d..ec26927 100644 --- a/F3:F303/Multistepper/usb_lib.h +++ b/F3:F303/Multistepper/usb_lib.h @@ -1,5 +1,4 @@ /* - * This file is part of the multistepper project. * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify @@ -15,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once #include @@ -92,16 +90,6 @@ enum{ #define LANG_US (uint16_t)0x0409 -#if 0 -typedef struct{ - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t *bString; -} string_descriptor_t; - -#define _USB_STRING_(name, str) string_descriptor_t name = {(sizeof(str) + 2), STRING_DESCRIPTOR, str} -#endif - #define _USB_STRING_(name, str) \ static const struct name \ { \ @@ -181,3 +169,4 @@ void clstate_handler(uint16_t val); void break_handler(); void vendor_handler(config_pack_t *packet); void chkin(); +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)()); diff --git a/F3:F303/Multistepper/usbhw.c b/F3:F303/Multistepper/usbhw.c index 9f6dc67..4f061b7 100644 --- a/F3:F303/Multistepper/usbhw.c +++ b/F3:F303/Multistepper/usbhw.c @@ -1,5 +1,4 @@ /* - * This file is part of the multistepper project. * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify @@ -15,109 +14,50 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include "usb.h" #include "usb_lib.h" // here we suppose that all PIN settings done in hw_setup earlier void USB_setup(){ +#if defined STM32F3 NVIC_DisableIRQ(USB_LP_IRQn); // remap USB LP & Wakeup interrupts to 75 and 76 - works only on pure F303 RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // enable tacting of SYSCFG SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP; +#elif defined STM32F1 + NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); + NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); +#elif defined STM32F0 + NVIC_DisableIRQ(USB_IRQn); + RCC->APB1ENR |= RCC_APB1ENR_CRSEN; + RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB + RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48 + uint32_t tmout = 16000000; + while(!(RCC->CR2 & RCC_CR2_HSI48RDY)){if(--tmout == 0) break;} + FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; + CRS->CFGR &= ~CRS_CFGR_SYNCSRC; + CRS->CFGR |= CRS_CFGR_SYNCSRC_1; // USB SOF selected as sync source + CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim + CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only + RCC->CFGR |= RCC_CFGR_SW; +#endif RCC->APB1ENR |= RCC_APB1ENR_USBEN; + //?? USB->CNTR = USB_CNTR_FRES; // Force USB Reset for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms - //uint32_t ctr = 0; USB->CNTR = 0; USB->BTABLE = 0; USB->DADDR = 0; USB->ISTR = 0; USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts +#if defined STM32F3 NVIC_EnableIRQ(USB_LP_IRQn); +#elif defined STM32F1 + NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); +#elif defined STM32F0 + USB->BCDR |= USB_BCDR_DPPU; + NVIC_EnableIRQ(USB_IRQn); +#endif } -static uint16_t lastaddr = LASTADDR_DEFAULT; -/** - * Endpoint initialisation - * @param number - EP num (0...7) - * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) - * @param txsz - transmission buffer size @ USB/CAN buffer - * @param rxsz - reception buffer size @ USB/CAN buffer - * @param uint16_t (*func)(ep_t *ep) - EP handler function - * @return 0 if all OK - */ -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ - if(number >= STM32ENDPOINTS) return 4; // out of configured amount - if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large - if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE/ACCESSZ) return 2; // out of btable - USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); - USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; - if(rxsz & 1 || rxsz > USB_BTABLE_SIZE) return 3; // wrong rx buffer size - uint16_t countrx = 0; - if(rxsz < 64) countrx = rxsz / 2; - else{ - if(rxsz & 0x1f) return 3; // should be multiple of 32 - countrx = 31 + rxsz / 32; - } - USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; - endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); - endpoints[number].txbufsz = txsz; - lastaddr += txsz; - USB_BTABLE->EP[number].USB_COUNT_TX = 0; - USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; - endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); - lastaddr += rxsz; - USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; - endpoints[number].func = func; - return 0; -} - -// standard IRQ handler -void usb_lp_isr(){ - if(USB->ISTR & USB_ISTR_RESET){ - usbON = 0; - // Reinit registers - USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; - // Endpoint 0 - CONTROL - // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! - lastaddr = LASTADDR_DEFAULT; - // clear address, leave only enable bit - USB->DADDR = USB_DADDR_EF; - if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ - return; - } - USB->ISTR = ~USB_ISTR_RESET; - } - if(USB->ISTR & USB_ISTR_CTR){ - // EP number - uint8_t n = USB->ISTR & USB_ISTR_EPID; - // copy status register - uint16_t epstatus = USB->EPnR[n]; - // copy received bytes amount - endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter - // check direction - if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) - if(n == 0){ // control endpoint - if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack - EP_Read(0, setupdatabuf); - // interrupt handler will be called later - }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf - EP_Read(0, ep0databuf); - } - } - } - // call EP handler - if(endpoints[n].func) endpoints[n].func(endpoints[n]); - } - if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep - usbON = 0; - USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; - USB->ISTR = ~USB_ISTR_SUSP; - } - if(USB->ISTR & USB_ISTR_WKUP){ // wakeup - USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags - USB->ISTR = ~USB_ISTR_WKUP; - } -} diff --git a/F3:F303/Multistepper/usbhw.h b/F3:F303/Multistepper/usbhw.h index 5915191..033846f 100644 --- a/F3:F303/Multistepper/usbhw.h +++ b/F3:F303/Multistepper/usbhw.h @@ -1,5 +1,4 @@ /* - * This file is part of the multistepper project. * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify @@ -15,17 +14,61 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once +#if defined STM32F0 +#include +#elif defined STM32F1 +#include +// there's no this define in standard header +#define USB_BASE ((uint32_t)0x40005C00) +#elif defined STM32F3 #include +#endif // max endpoints number #define STM32ENDPOINTS 8 /** * Buffers size definition **/ + +// F0 - USB2_16; F1 - USB1_16; F3 - 1/2 depending on series +#if !defined USB1_16 && !defined USB2_16 +#if defined STM32F0 +#define USB2_16 +#elif defined STM32F1 +#define USB1_16 +#else +#error "Can't determine USB1_16 or USB2_16, define by hands" +#endif +#endif + +// BTABLE_SIZE FOR STM32F3: +// In STM32F303/302xB/C, 512 bytes SRAM is not shared with CAN. +// In STM32F302x6/x8 and STM32F30xxD/E, 726 bytes dedicated SRAM and 256 bytes shared SRAM with CAN i.e. +// 1Kbytes dedicated SRAM in case CAN is disabled. +// remember, that USB_BTABLE_SIZE will be divided by ACCESSZ, so don't divide it twice for 32-bit addressing + +#ifdef NOCAN +#if defined STM32F0 +#define USB_BTABLE_SIZE 1024 +#elif defined STM32F3 +#define USB_BTABLE_SIZE 512 +#warning "Please, check real buffer size due to docs" +#else +#error "define STM32F0 or STM32F3" +#endif +#else // !NOCAN: F0/F3 with CAN or F1 (can't simultaneously run CAN and USB) +#if defined STM32F0 #define USB_BTABLE_SIZE 768 +#elif defined STM32F3 +#define USB_BTABLE_SIZE 726 +//#warning "Please, check real buffer size due to docs" +#else // STM32F103: 1024 bytes but with 32-bit addressing +#define USB_BTABLE_SIZE 1024 +#endif +#endif // NOCAN + // first 64 bytes of USB_BTABLE are registers! //#define USB_EP0_BASEADDR 64 // for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303) @@ -110,4 +153,3 @@ typedef struct{ } USB_BtableDef; void USB_setup(); -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)()); diff --git a/F3:F303/Multistepper/version.inc b/F3:F303/Multistepper/version.inc index 16d71ff..fd7e2e5 100644 --- a/F3:F303/Multistepper/version.inc +++ b/F3:F303/Multistepper/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "160" -#define BUILD_DATE "2024-08-26" +#define BUILD_NUMBER "164" +#define BUILD_DATE "2024-09-02" diff --git a/snippets/usb_pl2303/Readme b/snippets/usb_pl2303/Readme index 561ec82..cf9dc25 100644 --- a/snippets/usb_pl2303/Readme +++ b/snippets/usb_pl2303/Readme @@ -1 +1,9 @@ -Actual snipper for all MCUs (just fix usbhw.c and usbhw.h) \ No newline at end of file +Actual snipper for all MCUs (just fix usbhw.c and usbhw.h) + +If USB DP/DM pins need to be setting up, do it before calling USB_setup(). +For F1/F3 your should manulally turn off DP pullup before calling USB_setup() and turn it on after this. +F0 do it itself (excluding need of external pullup, e.g for halvanic isolator). + +defines: +NOCAN - no common work with CAN bus (for F0/F3) - buffer will be 256 bytes larger +USB1_16 (32-bit addressing) / USB2_16 (16-bit addressing) - addressing method of USB registers (manually define only for F3, where < D have 1_16, >= D have 2_16) diff --git a/snippets/usb_pl2303/ringbuffer.c b/snippets/usb_pl2303/ringbuffer.c new file mode 100644 index 0000000..8d8d6ca --- /dev/null +++ b/snippets/usb_pl2303/ringbuffer.c @@ -0,0 +1,167 @@ +/* + * Copyright 2023 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ringbuffer.h" + +static int datalen(ringbuffer *b){ + if(b->tail >= b->head) return (b->tail - b->head); + else return (b->length - b->head + b->tail); +} + +// stored data length +int RB_datalen(ringbuffer *b){ + if(b->busy) return -1; + b->busy = 1; + int l = datalen(b); + b->busy = 0; + return l; +} + +static int hasbyte(ringbuffer *b, uint8_t byte){ + if(b->head == b->tail) return -1; // no data in buffer + int startidx = b->head; + if(b->head > b->tail){ // + for(int found = b->head; found < b->length; ++found) + if(b->data[found] == byte) return found; + startidx = 0; + } + for(int found = startidx; found < b->tail; ++found) + if(b->data[found] == byte) return found; + return -1; +} + +/** + * @brief RB_hasbyte - check if buffer has given byte stored + * @param b - buffer + * @param byte - byte to find + * @return index if found, -1 if none or busy + */ +int RB_hasbyte(ringbuffer *b, uint8_t byte){ + if(b->busy) return -1; + b->busy = 1; + int ret = hasbyte(b, byte); + b->busy = 0; + return ret; +} + +// poor memcpy +static void mcpy(uint8_t *targ, const uint8_t *src, int l){ + while(l--) *targ++ = *src++; +} + +// increment head or tail +TRUE_INLINE void incr(ringbuffer *b, volatile int *what, int n){ + *what += n; + if(*what >= b->length) *what -= b->length; +} + +static int read(ringbuffer *b, uint8_t *s, int len){ + int l = datalen(b); + if(!l) return 0; + if(l > len) l = len; + int _1st = b->length - b->head; + if(_1st > l) _1st = l; + if(_1st > len) _1st = len; + mcpy(s, b->data + b->head, _1st); + if(_1st < len && l > _1st){ + mcpy(s+_1st, b->data, l - _1st); + incr(b, &b->head, l); + return l; + } + incr(b, &b->head, _1st); + return _1st; +} + +/** + * @brief RB_read - read data from ringbuffer + * @param b - buffer + * @param s - array to write data + * @param len - max len of `s` + * @return bytes read or -1 if busy + */ +int RB_read(ringbuffer *b, uint8_t *s, int len){ + if(b->busy) return -1; + b->busy = 1; + int r = read(b, s, len); + b->busy = 0; + return r; +} + +static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){ + int idx = hasbyte(b, byte); + if(idx < 0) return 0; + int partlen = idx + 1 - b->head; + // now calculate length of new data portion + if(idx < b->head) partlen += b->length; + if(partlen > len) return -read(b, s, len); + return read(b, s, partlen); +} + +/** + * @brief RB_readto fill array `s` with data until byte `byte` (with it) + * @param b - ringbuffer + * @param byte - check byte + * @param s - buffer to write data + * @param len - length of `s` + * @return amount of bytes written (negative, if lenbusy) return -1; + b->busy = 1; + int n = readto(b, byte, s, len); + b->busy = 0; + return n; +} + +static int write(ringbuffer *b, const uint8_t *str, int l){ + int r = b->length - 1 - datalen(b); // rest length + if(l > r) l = r; + if(!l) return 0; + int _1st = b->length - b->tail; + if(_1st > l) _1st = l; + mcpy(b->data + b->tail, str, _1st); + if(_1st < l){ // add another piece from start + mcpy(b->data, str+_1st, l-_1st); + } + incr(b, &b->tail, l); + return l; +} + +/** + * @brief RB_write - write some data to ringbuffer + * @param b - buffer + * @param str - data + * @param l - length + * @return amount of bytes written or -1 if busy + */ +int RB_write(ringbuffer *b, const uint8_t *str, int l){ + if(b->busy) return -1; + b->busy = 1; + int w = write(b, str, l); + b->busy = 0; + return w; +} + +// just delete all information in buffer `b` +int RB_clearbuf(ringbuffer *b){ + if(b->busy) return -1; + b->busy = 1; + b->head = 0; + b->tail = 0; + b->busy = 0; + return 1; +} diff --git a/snippets/usb_pl2303/ringbuffer.h b/snippets/usb_pl2303/ringbuffer.h new file mode 100644 index 0000000..ed2cf95 --- /dev/null +++ b/snippets/usb_pl2303/ringbuffer.h @@ -0,0 +1,41 @@ +/* + * Copyright 2023 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#if defined STM32F0 +#include +#elif defined STM32F1 +#include +#elif defined STM32F3 +#include +#endif + +typedef struct{ + uint8_t *data; // data buffer + const int length; // its length + int head; // head index + int tail; // tail index + volatile int busy; // == TRUE if buffer is busy now +} ringbuffer; + +int RB_read(ringbuffer *b, uint8_t *s, int len); +int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len); +int RB_hasbyte(ringbuffer *b, uint8_t byte); +int RB_write(ringbuffer *b, const uint8_t *str, int l); +int RB_datalen(ringbuffer *b); +int RB_clearbuf(ringbuffer *b); diff --git a/snippets/usb_pl2303/usb.c b/snippets/usb_pl2303/usb.c index 553b6cf..a2ee479 100644 --- a/snippets/usb_pl2303/usb.c +++ b/snippets/usb_pl2303/usb.c @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,18 +26,22 @@ static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending da static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ]; volatile ringbuffer rbout = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0}; volatile ringbuffer rbin = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0}; -// transmission is succesfull -volatile uint8_t bufisempty = 1; +// inbuf overflow when receiving volatile uint8_t bufovrfl = 0; +// last send data size +static volatile int lastdsz = 0; +// called from transmit EP void send_next(){ - if(bufisempty) return; - static int lastdsz = 0; int buflen = RB_read((ringbuffer*)&rbout, (uint8_t*)usbbuff, USB_TXBUFSZ); - if(!buflen){ + if(buflen == 0){ if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send lastdsz = 0; - bufisempty = 1; + return; + }else if(buflen < 0){ + lastdsz = 0; + // Uncomment next line if you want 4Mbit/s instead of 6Mbit/s + //EP_Write(3, NULL, 0); // send ZLP if buffer is in writting state now return; } EP_Write(3, (uint8_t*)usbbuff, buflen); @@ -47,44 +50,42 @@ void send_next(){ // blocking send full content of ring buffer int USB_sendall(){ - while(!bufisempty){ - if(!usbON) return 0; + while(lastdsz > 0){ + if(!usbON) return FALSE; } - return 1; + return TRUE; } // put `buf` into queue to send int USB_send(const uint8_t *buf, int len){ - if(!buf || !usbON || !len) return 0; + if(!buf || !usbON || !len) return FALSE; while(len){ int a = RB_write((ringbuffer*)&rbout, buf, len); - len -= a; - buf += a; - if(bufisempty){ - bufisempty = 0; - send_next(); - } + if(a > 0){ + len -= a; + buf += a; + } else if (a < 0) continue; // do nothing if buffer is in reading state + if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN } - return 1; + return TRUE; } int USB_putbyte(uint8_t byte){ - if(!usbON) return 0; - while(0 == RB_write((ringbuffer*)&rbout, &byte, 1)){ - if(bufisempty){ - bufisempty = 0; - send_next(); - } + if(!usbON) return FALSE; + int l = 0; + while((l = RB_write((ringbuffer*)&rbout, &byte, 1)) != 1){ + if(l < 0) continue; } - return 1; + if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN + return TRUE; } int USB_sendstr(const char *string){ - if(!string || !usbON) return 0; + if(!string || !usbON) return FALSE; int len = 0; const char *b = string; while(*b++) ++len; - if(!len) return 0; + if(!len) return FALSE; return USB_send((const uint8_t*)string, len); } @@ -95,13 +96,14 @@ int USB_sendstr(const char *string){ * @return amount of received bytes (negative, if overfull happened) */ int USB_receive(uint8_t *buf, int len){ - int sz = RB_read((ringbuffer*)&rbin, buf, len); + chkin(); if(bufovrfl){ - RB_clearbuf((ringbuffer*)&rbin); - if(!sz) sz = -1; - else sz = -sz; + while(1 != RB_clearbuf((ringbuffer*)&rbin)); bufovrfl = 0; + return -1; } + int sz = RB_read((ringbuffer*)&rbin, buf, len); + if(sz < 0) return 0; // buffer in writting state return sz; } @@ -112,15 +114,22 @@ int USB_receive(uint8_t *buf, int len){ * @return strlen or negative value indicating overflow (if so, string won't be ends with 0 and buffer should be cleared) */ int USB_receivestr(char *buf, int len){ - int l = RB_readto((ringbuffer*)&rbin, '\n', (uint8_t*)buf, len); - if(l == 0) return 0; - if(--l < 0 || bufovrfl) RB_clearbuf((ringbuffer*)&rbin); - else buf[l] = 0; // replace '\n' with strend + chkin(); if(bufovrfl){ - if(l > 0) l = -l; - else l = -1; + while(1 != RB_clearbuf((ringbuffer*)&rbin)); bufovrfl = 0; + return -1; } + int l = RB_readto((ringbuffer*)&rbin, '\n', (uint8_t*)buf, len); + if(l < 1){ + if(rbin.length == RB_datalen((ringbuffer*)&rbin)){ // buffer is full but no '\n' found + while(1 != RB_clearbuf((ringbuffer*)&rbin)); + return -1; + } + return 0; + } + if(l == 0) return 0; + buf[l-1] = 0; // replace '\n' with strend return l; } diff --git a/snippets/usb_pl2303/usb.h b/snippets/usb_pl2303/usb.h index 36d0d59..4583b9b 100644 --- a/snippets/usb_pl2303/usb.h +++ b/snippets/usb_pl2303/usb.h @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +22,7 @@ // sizes of ringbuffers for outgoing and incoming data #define RBOUTSZ (512) -#define RBINSZ (512) +#define RBINSZ (256) #define newline() USB_putbyte('\n') #define USND(s) do{USB_sendstr(s); USB_putbyte('\n');}while(0) diff --git a/snippets/usb_pl2303/usb_lib.c b/snippets/usb_pl2303/usb_lib.c index 49eb681..aea5344 100644 --- a/snippets/usb_pl2303/usb_lib.c +++ b/snippets/usb_pl2303/usb_lib.c @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include #include "usb.h" #include "usb_lib.h" @@ -26,7 +24,7 @@ ep_t endpoints[STM32ENDPOINTS]; static uint16_t USB_Addr = 0; static usb_LineCoding lineCoding = {115200, 0, 0, 8}; uint8_t ep0databuf[EP0DATABUF_SIZE], setupdatabuf[EP0DATABUF_SIZE]; -static config_pack_t *setup_packet = (config_pack_t*) setupdatabuf; +config_pack_t *setup_packet = (config_pack_t*) setupdatabuf; usb_LineCoding getLineCoding(){return lineCoding;} @@ -131,7 +129,7 @@ _USB_LANG_ID_(LD, LANG_US); _USB_STRING_(SD, u"0.0.1"); _USB_STRING_(MD, u"Prolific Technology Inc."); _USB_STRING_(PD, u"USB-Serial Controller"); -_USB_STRING_(ID, u"pl2303_emulator"); +_USB_STRING_(ID, u"USB-STM32"); static void const *StringDescriptor[iDESCR_AMOUNT] = { [iLANGUAGE_DESCR] = &LD, [iMANUFACTURER_DESCR] = &MD, @@ -266,15 +264,29 @@ static void transmit_Handler(){ // EP3IN send_next(); } +static uint8_t volatile rcvbuf[USB_RXBUFSZ]; +static uint8_t volatile rcvbuflen = 0; + +void chkin(){ + if(bufovrfl) return; + if(!rcvbuflen) return; + int w = RB_write((ringbuffer*)&rbin, (uint8_t*)rcvbuf, rcvbuflen); + if(w < 0) return; + if(w != rcvbuflen) bufovrfl = 1; + rcvbuflen = 0; + uint16_t status = KEEP_DTOG(USB->EPnR[2]); // don't change DTOG + USB->EPnR[2] = status ^ USB_EPnR_STAT_RX; +} + +// receiver reads data from local buffer and only then ACK'ed static void receive_Handler(){ // EP2OUT - uint8_t buf[USB_RXBUFSZ]; - uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]); - uint8_t sz = EP_Read(2, (uint8_t*)buf); - if(sz){ - if(RB_write((ringbuffer*)&rbin, buf, sz) != sz) bufovrfl = 1; + uint16_t status = KEEP_DTOG_STAT(USB->EPnR[2]); // don't change DTOG and NACK + if(rcvbuflen){ + bufovrfl = 1; // lost last data + rcvbuflen = 0; } - // keep stat_tx & set ACK rx, clear RX ctr - USB->EPnR[2] = (epstatus & ~USB_EPnR_CTR_RX) ^ USB_EPnR_STAT_RX; + rcvbuflen = EP_Read(2, (uint8_t*)rcvbuf); + USB->EPnR[2] = status & ~USB_EPnR_CTR_RX; } static inline void std_h2d_req(){ @@ -436,3 +448,103 @@ int EP_Read(uint8_t number, uint8_t *buf){ return sz; } + +static uint16_t lastaddr = LASTADDR_DEFAULT; +/** + * Endpoint initialisation + * @param number - EP num (0...7) + * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) + * @param txsz - transmission buffer size @ USB/CAN buffer + * @param rxsz - reception buffer size @ USB/CAN buffer + * @param uint16_t (*func)(ep_t *ep) - EP handler function + * @return 0 if all OK + */ +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ + if(number >= STM32ENDPOINTS) return 4; // out of configured amount + if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large + if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE/ACCESSZ) return 2; // out of btable + USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); + USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; + if(rxsz & 1 || rxsz > USB_BTABLE_SIZE) return 3; // wrong rx buffer size + uint16_t countrx = 0; + if(rxsz < 64) countrx = rxsz / 2; + else{ + if(rxsz & 0x1f) return 3; // should be multiple of 32 + countrx = 31 + rxsz / 32; + } + USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; + endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + endpoints[number].txbufsz = txsz; + lastaddr += txsz; + USB_BTABLE->EP[number].USB_COUNT_TX = 0; + USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; + endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + lastaddr += rxsz; + USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; + endpoints[number].func = func; + return 0; +} + +// standard IRQ handler +void USB_IRQ(){ + if(USB->ISTR & USB_ISTR_RESET){ + usbON = 0; + // Reinit registers + USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + // Endpoint 0 - CONTROL + // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! + lastaddr = LASTADDR_DEFAULT; + // clear address, leave only enable bit + USB->DADDR = USB_DADDR_EF; + if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ + return; + } + USB->ISTR = ~USB_ISTR_RESET; + } + if(USB->ISTR & USB_ISTR_CTR){ + // EP number + uint8_t n = USB->ISTR & USB_ISTR_EPID; + // copy status register + uint16_t epstatus = USB->EPnR[n]; + // copy received bytes amount + endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter + // check direction + if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) + if(n == 0){ // control endpoint + if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack + EP_Read(0, setupdatabuf); + // interrupt handler will be called later + }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf + EP_Read(0, ep0databuf); + } + } + } + // call EP handler + if(endpoints[n].func) endpoints[n].func(endpoints[n]); + } + if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep + usbON = 0; +#ifndef STM32F0 + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; +#else + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LPMODE; +#endif + USB->ISTR = ~USB_ISTR_SUSP; + } + if(USB->ISTR & USB_ISTR_WKUP){ // wakeup +#ifndef STM32F0 + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags +#else + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LPMODE); +#endif + USB->ISTR = ~USB_ISTR_WKUP; + } +} + +#if defined STM32F3 +void usb_lp_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F1 +void usb_lp_can_rx0_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32F0 +void usb_isr() __attribute__ ((alias ("USB_IRQ"))); +#endif diff --git a/snippets/usb_pl2303/usb_lib.h b/snippets/usb_pl2303/usb_lib.h index f76c276..ec26927 100644 --- a/snippets/usb_pl2303/usb_lib.h +++ b/snippets/usb_pl2303/usb_lib.h @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once #include @@ -156,6 +154,7 @@ typedef struct { extern ep_t endpoints[]; extern volatile uint8_t usbON; +extern config_pack_t *setup_packet; extern uint8_t ep0databuf[], setupdatabuf[]; void EP0_Handler(); @@ -169,3 +168,5 @@ void linecoding_handler(usb_LineCoding *lc); void clstate_handler(uint16_t val); void break_handler(); void vendor_handler(config_pack_t *packet); +void chkin(); +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)()); diff --git a/snippets/usb_pl2303/usbhw.c b/snippets/usb_pl2303/usbhw.c index 0b812e1..4f061b7 100644 --- a/snippets/usb_pl2303/usbhw.c +++ b/snippets/usb_pl2303/usbhw.c @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,109 +14,50 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include "usb.h" #include "usb_lib.h" // here we suppose that all PIN settings done in hw_setup earlier void USB_setup(){ +#if defined STM32F3 NVIC_DisableIRQ(USB_LP_IRQn); // remap USB LP & Wakeup interrupts to 75 and 76 - works only on pure F303 RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // enable tacting of SYSCFG SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP; +#elif defined STM32F1 + NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); + NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); +#elif defined STM32F0 + NVIC_DisableIRQ(USB_IRQn); + RCC->APB1ENR |= RCC_APB1ENR_CRSEN; + RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB + RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48 + uint32_t tmout = 16000000; + while(!(RCC->CR2 & RCC_CR2_HSI48RDY)){if(--tmout == 0) break;} + FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; + CRS->CFGR &= ~CRS_CFGR_SYNCSRC; + CRS->CFGR |= CRS_CFGR_SYNCSRC_1; // USB SOF selected as sync source + CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim + CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only + RCC->CFGR |= RCC_CFGR_SW; +#endif RCC->APB1ENR |= RCC_APB1ENR_USBEN; + //?? USB->CNTR = USB_CNTR_FRES; // Force USB Reset for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms - //uint32_t ctr = 0; USB->CNTR = 0; USB->BTABLE = 0; USB->DADDR = 0; USB->ISTR = 0; USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts +#if defined STM32F3 NVIC_EnableIRQ(USB_LP_IRQn); +#elif defined STM32F1 + NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); +#elif defined STM32F0 + USB->BCDR |= USB_BCDR_DPPU; + NVIC_EnableIRQ(USB_IRQn); +#endif } -static uint16_t lastaddr = LASTADDR_DEFAULT; -/** - * Endpoint initialisation - * @param number - EP num (0...7) - * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) - * @param txsz - transmission buffer size @ USB/CAN buffer - * @param rxsz - reception buffer size @ USB/CAN buffer - * @param uint16_t (*func)(ep_t *ep) - EP handler function - * @return 0 if all OK - */ -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ - if(number >= STM32ENDPOINTS) return 4; // out of configured amount - if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large - if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable - USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); - USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; - if(rxsz & 1 || rxsz > 512) return 3; // wrong rx buffer size - uint16_t countrx = 0; - if(rxsz < 64) countrx = rxsz / 2; - else{ - if(rxsz & 0x1f) return 3; // should be multiple of 32 - countrx = 31 + rxsz / 32; - } - USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; - endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); - endpoints[number].txbufsz = txsz; - lastaddr += txsz; - USB_BTABLE->EP[number].USB_COUNT_TX = 0; - USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; - endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); - lastaddr += rxsz; - USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; - endpoints[number].func = func; - return 0; -} - -// standard IRQ handler -void usb_lp_isr(){ - if(USB->ISTR & USB_ISTR_RESET){ - usbON = 0; - // Reinit registers - USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; - // Endpoint 0 - CONTROL - // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! - lastaddr = LASTADDR_DEFAULT; - // clear address, leave only enable bit - USB->DADDR = USB_DADDR_EF; - if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ - return; - } - USB->ISTR = ~USB_ISTR_RESET; - } - if(USB->ISTR & USB_ISTR_CTR){ - // EP number - uint8_t n = USB->ISTR & USB_ISTR_EPID; - // copy status register - uint16_t epstatus = USB->EPnR[n]; - // copy received bytes amount - endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter - // check direction - if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) - if(n == 0){ // control endpoint - if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack - EP_Read(0, setupdatabuf); - // interrupt handler will be called later - }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf - EP_Read(0, ep0databuf); - } - } - } - // call EP handler - if(endpoints[n].func) endpoints[n].func(endpoints[n]); - } - if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep - usbON = 0; - USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; - USB->ISTR = ~USB_ISTR_SUSP; - } - if(USB->ISTR & USB_ISTR_WKUP){ // wakeup - USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags - USB->ISTR = ~USB_ISTR_WKUP; - } -} diff --git a/snippets/usb_pl2303/usbhw.h b/snippets/usb_pl2303/usbhw.h index 167ec81..9944700 100644 --- a/snippets/usb_pl2303/usbhw.h +++ b/snippets/usb_pl2303/usbhw.h @@ -1,6 +1,5 @@ /* - * This file is part of the pl2303 project. - * Copyright 2023 Edward V. Emelianov . + * Copyright 2024 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,17 +14,61 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once +#if defined STM32F0 +#include +#elif defined STM32F1 +#include +// there's no this define in standard header +#define USB_BASE ((uint32_t)0x40005C00) +#elif defined STM32F3 #include +#endif // max endpoints number #define STM32ENDPOINTS 8 /** * Buffers size definition **/ + +// F0 - USB2_16; F1 - USB1_16; F3 - 1/2 depending on series +#if !defined USB1_16 && !defined USB2_16 +#if defined STM32F0 +#define USB2_16 +#elif defined STM32F1 +#define USB1_16 +#else +#error "Can't determine USB1_16 or USB2_16, define by hands" +#endif +#endif + +// BTABLE_SIZE FOR STM32F3: +// In STM32F303/302xB/C, 512 bytes SRAM is not shared with CAN. +// In STM32F302x6/x8 and STM32F30xxD/E, 726 bytes dedicated SRAM and 256 bytes shared SRAM with CAN i.e. +// 1Kbytes dedicated SRAM in case CAN is disabled. +// remember, that USB_BTABLE_SIZE will be divided by ACCESSZ, so don't divide it twice for 32-bit addressing + +#ifdef NOCAN +#if defined STM32F0 +#define USB_BTABLE_SIZE 1024 +#elif defined STM32F3 +#define USB_BTABLE_SIZE 512 +#warning "Please, check real buffer size due to docs" +#else +#error "define STM32F0 or STM32F3" +#endif +#else // !NOCAN: F0/F3 with CAN or F1 (can't simultaneously run CAN and USB) +#if defined STM32F0 #define USB_BTABLE_SIZE 768 +#elif defined STM32F3 +#define USB_BTABLE_SIZE 512 +#warning "Please, check real buffer size due to docs" +#else // STM32F103: 1024 bytes but with 32-bit addressing +#define USB_BTABLE_SIZE 1024 +#endif +#endif // NOCAN + // first 64 bytes of USB_BTABLE are registers! //#define USB_EP0_BASEADDR 64 // for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303) @@ -110,4 +153,3 @@ typedef struct{ } USB_BtableDef; void USB_setup(); -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)());