diff options
Diffstat (limited to 'bluefnorf')
-rw-r--r-- | bluefnorf/.gitignore | 8 | ||||
-rw-r--r-- | bluefnorf/Makefile | 41 | ||||
-rw-r--r-- | bluefnorf/main.c | 43 | ||||
-rw-r--r-- | bluefnorf/openocd.cfg | 8 | ||||
-rw-r--r-- | bluefnorf/stm32f103c8t6.ld | 14 | ||||
-rw-r--r-- | bluefnorf/usb.c | 241 | ||||
-rw-r--r-- | bluefnorf/usb.h | 12 |
7 files changed, 367 insertions, 0 deletions
diff --git a/bluefnorf/.gitignore b/bluefnorf/.gitignore new file mode 100644 index 0000000..2c6eb8b --- /dev/null +++ b/bluefnorf/.gitignore @@ -0,0 +1,8 @@ +*.bin +*.hex +*.o +*.elf +*.lst + +*.swp +*.swo diff --git a/bluefnorf/Makefile b/bluefnorf/Makefile new file mode 100644 index 0000000..b500a1b --- /dev/null +++ b/bluefnorf/Makefile @@ -0,0 +1,41 @@ + +OPENCM3_PATH ?= $(HOME)/resource/libopencm3 + +CC := arm-none-eabi-gcc +OBJCOPY := arm-none-eabi-objcopy +OBJDUMP := arm-none-eabi-objdump +SIZE := arm-none-eabi-size +AS = arm-none-eabi-as + +CFLAGS = -Wall -Wextra -g -std=gnu11 -O1 +CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3 -mfix-cortex-m3-ldrd -msoft-float +#CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections +#CFLAGS += -Wl,-Map=main.map +CFLAGS += -Tstm32f103c8t6.ld --static -nostartfiles +CFLAGS += -I$(OPENCM3_PATH)/include -L$(OPENCM3_PATH)/lib +CFLAGS += -DSTM32F1 + +LDFLAGS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group +LDFLAGS += -lopencm3_stm32f1 -lm + +all: main.elf + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +main.elf: main.o usb.o + $(CC) $(CFLAGS) -o main.elf main.o usb.o $(LDFLAGS) + + $(OBJCOPY) -O ihex $@ $(@:.elf=.hex) + $(OBJCOPY) -O binary $@ $(@:.elf=.bin) + $(OBJDUMP) -St $@ >$(@:.elf=.lst) + $(SIZE) $@ + +flash: main.elf + openocd -f openocd.cfg -c "program $< verify reset exit" + +clean: + rm -f $(addprefix main,.o .hex .lst .map .elf .bin) + +.PHONY: flash clean + diff --git a/bluefnorf/main.c b/bluefnorf/main.c new file mode 100644 index 0000000..540b41b --- /dev/null +++ b/bluefnorf/main.c @@ -0,0 +1,43 @@ +/* + * ADC test: Try to get as many samples as possible + * using fast interleave mode and DMA + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/gpio.h> +#include <libopencm3/stm32/adc.h> +#include <libopencm3/stm32/dma.h> + +#include "usb.h" + +int main(void) +{ + int i = 0; + // const char* line; + + // Clock Setup + rcc_clock_setup_in_hse_8mhz_out_72mhz(); + + // Initialize USB + usb_serial_init(); + + while (1) { + /* + if( i % 100000 == 0 ) { + // Read ADC + printf("Fnord 42 :: %d %d\r\n", _adc_samples[0], _adc_samples[1]); + } + */ + + i++; + } +} + +void hard_fault_handler(void) { + while (23); +} diff --git a/bluefnorf/openocd.cfg b/bluefnorf/openocd.cfg new file mode 100644 index 0000000..99e0019 --- /dev/null +++ b/bluefnorf/openocd.cfg @@ -0,0 +1,8 @@ + +telnet_port 4444 +gdb_port 3333 + +source [find interface/stlink-v2.cfg] + +source [find target/stm32f1x.cfg] + diff --git a/bluefnorf/stm32f103c8t6.ld b/bluefnorf/stm32f103c8t6.ld new file mode 100644 index 0000000..f70bbb7 --- /dev/null +++ b/bluefnorf/stm32f103c8t6.ld @@ -0,0 +1,14 @@ + +__estack = 0x20005000; + + +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + + +/* Include the common ld script. */ +INCLUDE cortex-m-generic.ld + diff --git a/bluefnorf/usb.c b/bluefnorf/usb.c new file mode 100644 index 0000000..00f363d --- /dev/null +++ b/bluefnorf/usb.c @@ -0,0 +1,241 @@ + + +/* + * Initialize USB ACM serial device, provide convenience + * function for serial communication. + * + * Mostly plucked together from some opencm3 example code. + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/gpio.h> +#include <libopencm3/usb/usbd.h> +#include <libopencm3/usb/cdc.h> +#include <libopencm3/cm3/nvic.h> + +#include "usb.h" + +#define STATUS_LED_PORT GPIOC +#define STATUS_LED_PIN GPIO13 + +#define USBD_PORT GPIOA +#define USBDM GPIO11 +#define USBDP GPIO12 + +#define RX_ECHO 1 +#define RX_BUF_LEN 256 + +static char rx_tmp[RX_BUF_LEN]; +static char rx_buf[RX_BUF_LEN]; + +static size_t rx_tmp_len; +static uint8_t rx_buf_ready; + +static usbd_device *usbd_dev; + +/* Buffer to be used for control requests. */ +uint8_t usbd_control_buffer[128]; + +static const struct usb_device_descriptor device_descriptor = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0xfe, // USB_CLASS_CDC, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x1209, + .idProduct = 0x4001, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +static const struct usb_endpoint_descriptor comm_endp[] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x83, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 16, + .bInterval = 255, +}}; + +static const struct usb_endpoint_descriptor data_endp[] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, +}, { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, +}}; + +static const struct usb_interface_descriptor comm_iface[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = 0xfe, // USB_CLASS_CDC, + .bInterfaceSubClass = 0x00, // USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = 0x00, // USB_CDC_PROTOCOL_AT, + .iInterface = 0, + + .endpoint = comm_endp, + + .extra = NULL, // &cdcacm_functional_descriptors, + .extralen = 0, +}}; + +static const struct usb_interface_descriptor data_iface[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_DATA, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, + + .endpoint = data_endp, +}}; + +static const struct usb_interface ifaces[] = {{ + .num_altsetting = 1, + .altsetting = comm_iface, +}, { + .num_altsetting = 1, + .altsetting = data_iface, +}}; + +static const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 2, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x32, + + .interface = ifaces, +}; + + +static const char *usb_strings[] = { + "Chaos Computer Club Berlin e.V.", + "bluefnorf", + "bf1", +}; + + +void usb_gpio_init() { + // Clock + rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_GPIOC); + + // D+ + gpio_set_mode(USBD_PORT, + GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, + USBDP); + + // LED + gpio_set_mode(STATUS_LED_PORT, + GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, + STATUS_LED_PIN); + +} + +void usb_status_led_toggle() { + gpio_toggle(STATUS_LED_PORT, STATUS_LED_PIN); +} + +static void usb_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) { + char buf[64]; + + int len = usbd_ep_read_packet(usbd_dev, ep, buf, 64); + + if (len) { + usbd_ep_write_packet(usbd_dev, 0x82, buf, len); + } +} + +static enum usbd_request_return_codes usb_control_request_cb(usbd_device *usbd_dev, struct usb_setup_data *req, + uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete) { + (void)usbd_dev; + (void)req; + (void)buf; + (void)len; + (void)complete; + return 0; +} + +static void usb_set_config_cb(usbd_device *usbd_dev, uint16_t wValue) { + (void)wValue; + + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, usb_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); + + usbd_register_control_callback( + usbd_dev, + USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + usb_control_request_cb + ); +} + +usbd_device *usb_serial_init() { + // Initialize GPIO + usb_gpio_init(); + + // Initialize buffers + memset(rx_tmp, 0, RX_BUF_LEN); + memset(rx_buf, 0, RX_BUF_LEN); + + rx_tmp_len = 0; + rx_buf_ready = 0; + + // Pull down D+ + gpio_clear(USBD_PORT, USBDP); + for (int i = 0; i < 0x10000; i++) { + __asm__("nop"); + } + gpio_set(USBD_PORT, USBDP); + + // Initialize usb device + usbd_dev = usbd_init(&st_usbfs_v1_usb_driver, + &device_descriptor, + &config, + usb_strings, 3, + usbd_control_buffer, sizeof(usbd_control_buffer)); + + usbd_register_set_config_callback(usbd_dev, usb_set_config_cb); + + // Pull down + gpio_clear(USBD_PORT, USBDP); + + nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); + + return usbd_dev; +} + +void usb_lp_can_rx0_isr() { + usbd_poll(usbd_dev); + nvic_clear_pending_irq(NVIC_USB_LP_CAN_RX0_IRQ); +} diff --git a/bluefnorf/usb.h b/bluefnorf/usb.h new file mode 100644 index 0000000..ad75684 --- /dev/null +++ b/bluefnorf/usb.h @@ -0,0 +1,12 @@ +#ifndef __USB_H__ +#define __USB_H__ + +#include <libopencm3/usb/usbd.h> + +usbd_device* usb_serial_init(); +const char* usb_serial_rx(); +size_t usb_serial_tx(const char*, size_t); + + +#endif + |