Lisa/M board tests

This commit is contained in:
Martin Mueller
2010-12-05 23:59:12 +01:00
parent e0cd352990
commit 963588aba0
27 changed files with 2593 additions and 5 deletions

View File

@@ -0,0 +1,99 @@
##
## This file is part of the libopenstm32 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
BINARY = usbhid
PREFIX=/opt/paparazzi/stm32/bin/arm-none-eabi
# PREFIX ?= arm-none-eabi
#PREFIX ?= arm-elf
CC = $(PREFIX)-gcc
LD = $(PREFIX)-gcc
OBJCOPY = $(PREFIX)-objcopy
OBJDUMP = $(PREFIX)-objdump
# Uncomment this line if you want to use the installed (not local) library.
#TOOLCHAIN_DIR = `dirname \`which $(CC)\``/..
TOOLCHAIN_DIR = ../../..
CFLAGS = -O0 -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \
-mcpu=cortex-m3 -mthumb
LDSCRIPT = $(BINARY).ld
LDFLAGS = -L$(TOOLCHAIN_DIR)/lib -T$(LDSCRIPT) -nostartfiles
OBJS = $(BINARY).o
#OPENOCD_BASE = /usr
OPENOCD_BASE = /opt/paparazzi/stm32
OPENOCD = $(OPENOCD_BASE)/bin/openocd
OPENOCD_SCRIPTS = $(OPENOCD_BASE)/share/openocd/scripts
#OPENOCD_FLASHER = $(OPENOCD_SCRIPTS)/interface/openocd-usb.cfg
OPENOCD_FLASHER = $(OPENOCD_SCRIPTS)/interface/jtagkey-tiny.cfg
#OPENOCD_BOARD = $(OPENOCD_SCRIPTS)/board/paparazzi_lisa_m.cfg
OPENOCD_BOARD = /opt/paparazzi/stm32/share/openocd/scripts/board/lisa-l.cfg
# Be silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
Q := @
NULL := 2>/dev/null
endif
all: images
images: $(BINARY)
@printf " OBJCOPY $(BINARY).bin\n"
$(Q)$(OBJCOPY) -Obinary $(BINARY) $(BINARY).bin
@printf " OBJCOPY $(BINARY).hex\n"
$(Q)$(OBJCOPY) -Oihex $(BINARY) $(BINARY).hex
@printf " OBJCOPY $(BINARY).srec\n"
$(Q)$(OBJCOPY) -Osrec $(BINARY) $(BINARY).srec
@printf " OBJDUMP $(BINARY).list\n"
$(Q)$(OBJDUMP) -S $(BINARY) > $(BINARY).list
$(BINARY): $(OBJS) $(LDSCRIPT)
@printf " LD $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(LD) $(LDFLAGS) -o $(BINARY) $(OBJS) -lopenstm32
%.o: %.c Makefile
@printf " CC $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(CC) $(CFLAGS) -o $@ -c $<
clean:
@printf " CLEAN $(subst $(shell pwd)/,,$(OBJS))\n"
$(Q)rm -f *.o
@printf " CLEAN $(BINARY)\n"
$(Q)rm -f $(BINARY)
@printf " CLEAN $(BINARY).bin\n"
$(Q)rm -f $(BINARY).bin
@printf " CLEAN $(BINARY).hex\n"
$(Q)rm -f $(BINARY).hex
@printf " CLEAN $(BINARY).srec\n"
$(Q)rm -f $(BINARY).srec
@printf " CLEAN $(BINARY).list\n"
$(Q)rm -f $(BINARY).list
flash: images
@printf " FLASH $(BINARY).bin\n"
@# IMPORTANT: Don't use "resume", only "reset" will work correctly!
$(Q)$(OPENOCD) -s $(OPENOCD_SCRIPTS) \
-f $(OPENOCD_FLASHER) \
-f $(OPENOCD_BOARD) \
-c "init" -c "reset halt" \
-c "flash write_image erase $(BINARY).hex" \
-c "reset" \
-c "shutdown" $(NULL)
.PHONY: images clean

View File

@@ -0,0 +1,43 @@
------------------------------------------------------------------------------
README
------------------------------------------------------------------------------
This example implements a USB Human Interface Device (HID)
to demonstrate the use of the USB device stack.
Building
--------
$ make
Running 'make' on the top-level libopenstm32 directory will automatically
also build this example. Or you can build the library "manually" and
then run 'make' in this directory.
You may want to override the toolchain (e.g., arm-elf or arm-none-eabi):
$ PREFIX=arm-none-eabi make
For a more verbose build you can use
$ make V=1
Flashing
--------
You can flash the generated code using OpenOCD:
$ make flash
Or you can do the same manually via:
$ openocd -f interface/jtagkey-tiny.cfg -f target/stm32.cfg
$ telnet localhost 4444
> reset halt
> flash write_image erase systick.hex
> reset
Replace the "jtagkey-tiny.cfg" with whatever JTAG device you are using, and/or
replace "stm.cfg" with your respective config file.

View File

@@ -0,0 +1,38 @@
/*
* This file is part of the libopenstm32 project.
*
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __HID_H
#define __HID_H
#include <stdint.h>
#define USB_CLASS_HID 3
#define USB_DT_HID 0x21
#define USB_DT_REPORT 0x22
struct usb_hid_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
} __attribute__((packed));
#endif

View File

@@ -0,0 +1,286 @@
/*
* This file is part of the libopenstm32 project.
*
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <libopenstm32/rcc.h>
#include <libopenstm32/gpio.h>
#include <libopenstm32/systick.h>
#include <usbd.h>
#include <stdlib.h>
#include "hid.h"
/* Define this to include the DFU APP interface. */
#define INCLUDE_DFU_INTERFACE
#ifdef INCLUDE_DFU_INTERFACE
# include <libopenstm32/scb.h>
# include "../usb_dfu/dfu.h"
#endif
const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = 0,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = 64,
.idVendor = 0x0483,
.idProduct = 0x5710,
.bcdDevice = 0x0200,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
};
/* I have no idea what this means. I haven't read the HID spec. */
static const u8 hid_report_descriptor[] = {
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38,
0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, 0x03,
0x81, 0x06, 0xC0, 0x09, 0x3c, 0x05, 0xff, 0x09,
0x01, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95,
0x02, 0xb1, 0x22, 0x75, 0x06, 0x95, 0x01, 0xb1,
0x01, 0xc0
};
static const struct {
struct usb_hid_descriptor hid_descriptor;
struct {
uint8_t bReportDescriptorType;
uint16_t wDescriptorLength;
} __attribute__((packed)) hid_report;
} __attribute__((packed)) hid_function = {
.hid_descriptor = {
.bLength = sizeof(hid_function),
.bDescriptorType = USB_DT_HID,
.bcdHID = 0x0100,
.bCountryCode = 0,
.bNumDescriptors = 1,
},
.hid_report = {
.bReportDescriptorType = USB_DT_REPORT,
.wDescriptorLength = sizeof(hid_report_descriptor),
}
};
const struct usb_endpoint_descriptor hid_endpoint = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 4,
.bInterval = 0x20,
};
const struct usb_interface_descriptor hid_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_HID,
.bInterfaceSubClass = 1, /* boot */
.bInterfaceProtocol = 2, /* mouse */
.iInterface = 0,
.endpoint = &hid_endpoint,
.extra = &hid_function,
.extralen = sizeof(hid_function),
};
#ifdef INCLUDE_DFU_INTERFACE
const struct usb_dfu_descriptor dfu_function = {
.bLength = sizeof(struct usb_dfu_descriptor),
.bDescriptorType = DFU_FUNCTIONAL,
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.wDetachTimeout = 255,
.wTransferSize = 1024,
.bcdDFUVersion = 0x011A,
};
const struct usb_interface_descriptor dfu_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 1,
.bAlternateSetting = 0,
.bNumEndpoints = 0,
.bInterfaceClass = 0xFE,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 1,
.iInterface = 0,
.extra = &dfu_function,
.extralen = sizeof(dfu_function),
};
#endif
const struct usb_interface ifaces[] = {{
.num_altsetting = 1,
.altsetting = &hid_iface,
#ifdef INCLUDE_DFU_INTERFACE
}, {
.num_altsetting = 1,
.altsetting = &dfu_iface,
#endif
}};
const struct usb_config_descriptor config = {
.bLength = USB_DT_CONFIGURATION_SIZE,
.bDescriptorType = USB_DT_CONFIGURATION,
.wTotalLength = 0,
#ifdef INCLUDE_DFU_INTERFACE
.bNumInterfaces = 2,
#else
.bNumInterfaces = 1,
#endif
.bConfigurationValue = 1,
.iConfiguration = 0,
.bmAttributes = 0xC0,
.bMaxPower = 0x32,
.interface = ifaces,
};
static const char *usb_strings[] = {
"x",
"Black Sphere Technologies",
"HID Demo",
"DEMO",
};
static int hid_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
void (**complete)(struct usb_setup_data *req))
{
(void)complete;
if((req->bmRequestType != 0x81) ||
(req->bRequest != USB_REQ_GET_DESCRIPTOR) ||
(req->wValue != 0x2200))
return 0;
/* Handle the HID report descriptor */
*buf = (u8*)hid_report_descriptor;
*len = sizeof(hid_report_descriptor);
return 1;
}
#ifdef INCLUDE_DFU_INTERFACE
static void dfu_detach_complete(struct usb_setup_data *req)
{
(void)req;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO10);
gpio_set(GPIOA, GPIO10);
scb_reset_core();
}
static int dfu_control_command(struct usb_setup_data *req,
void (**complete)(struct usb_setup_data *req))
{
if((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH))
return 0; /* Only accept class request */
*complete = dfu_detach_complete;
return 1;
}
#endif
static void hid_set_config(u16 wValue)
{
(void)wValue;
usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL);
usbd_register_control_read_callback(hid_control_read);
#ifdef INCLUDE_DFU_INTERFACE
usbd_register_control_command_callback(dfu_control_command);
#endif
systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
systick_set_reload(100000);
systick_interrupt_enable();
systick_counter_enable();
}
int main(void)
{
rcc_clock_setup_in_hsi_out_48mhz();
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_IOPCEN);
/* USB_DETECT as input */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO8);
/* disconnect USB_DISC, as output */
gpio_set(GPIOC, GPIO15);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
/* green LED off, as output */
gpio_clear(GPIOC, GPIO13);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
usbd_init(&dev, &config, usb_strings);
usbd_register_set_config_callback(hid_set_config);
/* delay some seconds to show that pull-up switch works */
{int i; for (i=0;i<0x800000;i++);}
/* wait for USB Vbus */
while(gpio_get(GPIOA, GPIO8) == 0);
/* green LED on, connect USB */
gpio_set(GPIOC, GPIO13);
gpio_clear(GPIOC, GPIO15);
while (1)
usbd_poll();
}
void sys_tick_handler(void)
{
static int x = 0;
static int dir = 1;
uint8_t buf[4] = {0, 0, 0, 0};
buf[1] = dir;
x += dir;
if(x > 30) dir = -dir;
if(x < -30) dir = -dir;
usbd_ep_write_packet(0x81, buf, 4);
}

View File

@@ -0,0 +1,32 @@
/*
* This file is part of the libopenstm32 project.
*
* Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/* Linker script for Olimex STM32-H103 (STM32F103RBT6, 128K flash, 20K RAM). */
/* Define memory regions. */
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
}
/* Include the common ld script from libopenstm32. */
INCLUDE libopenstm32.ld