stlink: Add the UART
This commit is contained in:
parent
35d6adc236
commit
67f8176c5b
|
@ -3,7 +3,7 @@ CC = $(CROSS_COMPILE)gcc
|
|||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
|
||||
CFLAGS += -mcpu=cortex-m3 -mthumb \
|
||||
-DSTM32F1 -I../libopencm3/include
|
||||
-DSTM32F1 -I../libopencm3/include -Iplatforms/stlink -Iplatforms/stm32
|
||||
LDFLAGS = -lopencm3_stm32f1 -Wl,--defsym,_stack=0x20005000 \
|
||||
-Wl,-T,platforms/stm32/stlink.ld -nostartfiles -lc -lnosys \
|
||||
-Wl,-Map=mapfile -mthumb -mcpu=cortex-m3 -Wl,-gc-sections \
|
||||
|
@ -13,6 +13,7 @@ VPATH += platforms/stm32
|
|||
|
||||
SRC += cdcacm.c \
|
||||
platform.c \
|
||||
platforms/native/usbuart.c \
|
||||
|
||||
all: blackmagic.bin
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include <usbuart.h>
|
||||
|
||||
usbd_device * usbdev;
|
||||
|
||||
|
@ -167,6 +168,109 @@ static const struct usb_iface_assoc_descriptor gdb_assoc = {
|
|||
.iFunction = 0,
|
||||
};
|
||||
|
||||
/* Serial ACM interface */
|
||||
static const struct usb_endpoint_descriptor uart_comm_endp[] = {{
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x84,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||
.wMaxPacketSize = 16,
|
||||
.bInterval = 255,
|
||||
}};
|
||||
|
||||
static const struct usb_endpoint_descriptor uart_data_endp[] = {{
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x03,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||
.wMaxPacketSize = CDCACM_PACKET_SIZE,
|
||||
.bInterval = 1,
|
||||
}, {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x83,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||
.wMaxPacketSize = CDCACM_PACKET_SIZE,
|
||||
.bInterval = 1,
|
||||
}};
|
||||
|
||||
static const struct {
|
||||
struct usb_cdc_header_descriptor header;
|
||||
struct usb_cdc_call_management_descriptor call_mgmt;
|
||||
struct usb_cdc_acm_descriptor acm;
|
||||
struct usb_cdc_union_descriptor cdc_union;
|
||||
} __attribute__((packed)) uart_cdcacm_functional_descriptors = {
|
||||
.header = {
|
||||
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
|
||||
.bDescriptorType = CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
|
||||
.bcdCDC = 0x0110,
|
||||
},
|
||||
.call_mgmt = {
|
||||
.bFunctionLength =
|
||||
sizeof(struct usb_cdc_call_management_descriptor),
|
||||
.bDescriptorType = CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
|
||||
.bmCapabilities = 0,
|
||||
.bDataInterface = 3,
|
||||
},
|
||||
.acm = {
|
||||
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
|
||||
.bDescriptorType = CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
|
||||
.bmCapabilities = 2, /* SET_LINE_CODING supported*/
|
||||
},
|
||||
.cdc_union = {
|
||||
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
|
||||
.bDescriptorType = CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
|
||||
.bControlInterface = 2,
|
||||
.bSubordinateInterface0 = 3,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct usb_interface_descriptor uart_comm_iface[] = {{
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 2,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 1,
|
||||
.bInterfaceClass = USB_CLASS_CDC,
|
||||
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
||||
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
|
||||
.iInterface = 5,
|
||||
|
||||
.endpoint = uart_comm_endp,
|
||||
|
||||
.extra = &uart_cdcacm_functional_descriptors,
|
||||
.extralen = sizeof(uart_cdcacm_functional_descriptors)
|
||||
}};
|
||||
|
||||
static const struct usb_interface_descriptor uart_data_iface[] = {{
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 3,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_DATA,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = 0,
|
||||
|
||||
.endpoint = uart_data_endp,
|
||||
}};
|
||||
|
||||
static const struct usb_iface_assoc_descriptor uart_assoc = {
|
||||
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
|
||||
.bFirstInterface = 2,
|
||||
.bInterfaceCount = 2,
|
||||
.bFunctionClass = USB_CLASS_CDC,
|
||||
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
|
||||
.bFunctionProtocol = USB_CDC_PROTOCOL_AT,
|
||||
.iFunction = 0,
|
||||
};
|
||||
|
||||
static const struct usb_interface ifaces[] = {{
|
||||
.num_altsetting = 1,
|
||||
.iface_assoc = &gdb_assoc,
|
||||
|
@ -174,13 +278,20 @@ static const struct usb_interface ifaces[] = {{
|
|||
}, {
|
||||
.num_altsetting = 1,
|
||||
.altsetting = gdb_data_iface,
|
||||
}, {
|
||||
.num_altsetting = 1,
|
||||
.iface_assoc = &uart_assoc,
|
||||
.altsetting = uart_comm_iface,
|
||||
}, {
|
||||
.num_altsetting = 1,
|
||||
.altsetting = uart_data_iface,
|
||||
}};
|
||||
|
||||
static const struct usb_config_descriptor config = {
|
||||
.bLength = USB_DT_CONFIGURATION_SIZE,
|
||||
.bDescriptorType = USB_DT_CONFIGURATION,
|
||||
.wTotalLength = 0,
|
||||
.bNumInterfaces = 2,
|
||||
.bNumInterfaces = 4,
|
||||
.bConfigurationValue = 1,
|
||||
.iConfiguration = 0,
|
||||
.bmAttributes = 0x80,
|
||||
|
@ -192,15 +303,14 @@ static const struct usb_config_descriptor config = {
|
|||
char serial_no[9];
|
||||
|
||||
static const char *usb_strings[] = {
|
||||
"x",
|
||||
"Black Sphere Technologies",
|
||||
"Black Magic Probe",
|
||||
serial_no,
|
||||
"Black Magic GDB Server",
|
||||
"Black Magic UART Port",
|
||||
};
|
||||
|
||||
static int cdcacm_control_request(
|
||||
usbd_device *dev,
|
||||
static int cdcacm_control_request(usbd_device *dev,
|
||||
struct usb_setup_data *req, uint8_t **buf, uint16_t *len,
|
||||
void (**complete)(usbd_device *dev, struct usb_setup_data *req))
|
||||
{
|
||||
|
@ -223,6 +333,8 @@ static int cdcacm_control_request(
|
|||
return 0;
|
||||
|
||||
switch(req->wIndex) {
|
||||
case 2:
|
||||
usbuart_set_line_coding((struct usb_cdc_line_coding*)*buf);
|
||||
case 0:
|
||||
return 1; /* Ignore on GDB Port */
|
||||
default:
|
||||
|
@ -253,6 +365,13 @@ static void cdcacm_set_config(usbd_device *dev, u16 wValue)
|
|||
CDCACM_PACKET_SIZE, NULL);
|
||||
usbd_ep_setup(dev, 0x82, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||
|
||||
/* Serial interface */
|
||||
usbd_ep_setup(dev, 0x03, USB_ENDPOINT_ATTR_BULK,
|
||||
CDCACM_PACKET_SIZE, usbuart_usb_out_cb);
|
||||
usbd_ep_setup(dev, 0x83, USB_ENDPOINT_ATTR_BULK,
|
||||
CDCACM_PACKET_SIZE, usbuart_usb_in_cb);
|
||||
usbd_ep_setup(dev, 0x84, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||
|
||||
usbd_register_control_callback(dev,
|
||||
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
|
||||
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
|
||||
|
@ -272,6 +391,8 @@ static void cdcacm_set_config(usbd_device *dev, u16 wValue)
|
|||
buf[8] = 3; /* DCD | DSR */
|
||||
buf[9] = 0;
|
||||
usbd_ep_write_packet(dev, 0x82, buf, 10);
|
||||
notif->wIndex = 2;
|
||||
usbd_ep_write_packet(dev, 0x84, buf, 10);
|
||||
}
|
||||
|
||||
/* We need a special large control buffer for this device: */
|
||||
|
@ -284,10 +405,11 @@ void cdcacm_init(void)
|
|||
get_dev_unique_id(serial_no);
|
||||
|
||||
usbdev = usbd_init(&stm32f103_usb_driver,
|
||||
&dev, &config, usb_strings, 7);
|
||||
&dev, &config, usb_strings, 5);
|
||||
usbd_set_control_buffer_size(usbdev, sizeof(usbd_control_buffer));
|
||||
usbd_register_set_config_callback(usbdev, cdcacm_set_config);
|
||||
|
||||
nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, IRQ_PRI_USB);
|
||||
nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "platform.h"
|
||||
#include "jtag_scan.h"
|
||||
#include <usbuart.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
@ -48,6 +49,7 @@ int platform_init(void)
|
|||
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN);
|
||||
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
|
||||
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
|
||||
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
|
||||
|
||||
/* Setup GPIO ports */
|
||||
gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ,
|
||||
|
@ -63,9 +65,15 @@ int platform_init(void)
|
|||
/* Setup heartbeat timer */
|
||||
systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
|
||||
systick_set_reload(900000); /* Interrupt us at 10 Hz */
|
||||
SCB_SHPR(11) &= ~((15 << 4) & 0xff);
|
||||
SCB_SHPR(11) |= ((14 << 4) & 0xff);
|
||||
systick_interrupt_enable();
|
||||
systick_counter_enable();
|
||||
|
||||
usbuart_init();
|
||||
|
||||
SCB_VTOR = 0x2000; // Relocate interrupt vector table here
|
||||
|
||||
cdcacm_init();
|
||||
|
||||
jtag_scan(NULL);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
extern usbd_device *usbdev;
|
||||
#define CDCACM_GDB_ENDPOINT 1
|
||||
#define CDCACM_UART_ENDPOINT 3
|
||||
|
||||
/* Important pin mappings for STM32 implementation:
|
||||
*
|
||||
|
@ -75,8 +76,29 @@ extern usbd_device *usbdev;
|
|||
#define SWCLK_PIN TCK_PIN
|
||||
|
||||
#define LED_PORT GPIOA
|
||||
/* Use PC14 for a "dummy" uart led. So we can observere at least with scope*/
|
||||
#define LED_PORT_UART GPIOC
|
||||
#define LED_UART GPIO14
|
||||
#define LED_IDLE_RUN GPIO8
|
||||
|
||||
/* Interrupt priorities. Low numbers are high priority.
|
||||
* For now USART2 preempts USB which may spin while buffer is drained.
|
||||
* TIM3 is used for traceswo capture and must be highest priority.
|
||||
*/
|
||||
#define IRQ_PRI_USB (2 << 4)
|
||||
#define IRQ_PRI_USBUSART (1 << 4)
|
||||
#define IRQ_PRI_USB_VBUS (14 << 4)
|
||||
#define IRQ_PRI_TIM3 (0 << 4)
|
||||
|
||||
#define USBUSART USART2
|
||||
#define USBUSART_CR1 USART2_CR1
|
||||
#define USBUSART_IRQ NVIC_USART2_IRQ
|
||||
#define USBUSART_APB_ENR RCC_APB1ENR
|
||||
#define USBUSART_CLK_ENABLE RCC_APB1ENR_USART2EN
|
||||
#define USBUSART_PORT GPIOA
|
||||
#define USBUSART_TX_PIN GPIO2
|
||||
#define USBUSART_ISR usart2_isr
|
||||
|
||||
#define DEBUG(...)
|
||||
|
||||
extern uint8_t running_status;
|
||||
|
@ -116,6 +138,9 @@ void cdcacm_init(void);
|
|||
int cdcacm_get_config(void);
|
||||
int cdcacm_get_dtr(void);
|
||||
|
||||
/* <platform.h> */
|
||||
void uart_usb_buf_drain(uint8_t ep);
|
||||
|
||||
/* Use newlib provided integer only stdio functions */
|
||||
#define sscanf siscanf
|
||||
#define sprintf siprintf
|
||||
|
|
Loading…
Reference in New Issue