Renamed current lisa-m tests to lisa-m-1 as it differs a bit from v2.

This commit is contained in:
Piotr Esden-Tempski
2012-02-21 13:51:56 -08:00
parent bffbb0e54d
commit c654b2199a
16 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
##
## This file is part of the libopencm3 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 = can
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include

View File

@@ -0,0 +1,232 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
*
* 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 <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/flash.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/nvic.h>
#include <libopencm3/stm32/systick.h>
#include <libopencm3/stm32/can.h>
struct can_tx_msg {
u32 std_id;
u32 ext_id;
u8 ide;
u8 rtr;
u8 dlc;
u8 data[8];
};
struct can_rx_msg {
u32 std_id;
u32 ext_id;
u8 ide;
u8 rtr;
u8 dlc;
u8 data[8];
u8 fmi;
};
struct can_tx_msg can_tx_msg;
struct can_rx_msg can_rx_msg;
void gpio_setup(void)
{
/* Enable Alternate Function clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
/* Enable GPIOA clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
/* Enable GPIOB clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
/* Enable GPIOC clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
/* Preconfigure LEDs. */
gpio_set(GPIOA, GPIO8); /* LED0 off */
gpio_set(GPIOB, GPIO4); /* LED1 off */
gpio_set(GPIOC, GPIO15); /* LED2 off */
gpio_set(GPIOC, GPIO2); /* LED3 off */
gpio_set(GPIOC, GPIO5); /* LED4 off */
/* Configure LED GPIOOs. */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO8);
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO4);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO2);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO5);
/* Configure PB4 as GPIO. */
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST;
}
void systick_setup(void)
{
/* 72MHz / 8 => 9000000 counts per second */
systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
/* 9000000/9000 = 1000 overflows per second - every 1ms one interrupt */
systick_set_reload(9000);
systick_interrupt_enable();
/* Start counting. */
systick_counter_enable();
}
void can_setup(void)
{
/* Enable peripheral clocks. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CANEN);
AFIO_MAPR = AFIO_MAPR_CAN1_REMAP_PORTB;
/* Configure CAN pin: RX (input pull-up). */
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX);
gpio_set(GPIOB, GPIO_CAN1_PB_RX);
/* Configure CAN pin: TX. */
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX);
/* NVIC setup. */
nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ);
nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1);
/* Reset CAN. */
can_reset(CAN1);
/* CAN cell init. */
if (can_init(CAN1,
false, /* TTCM: Time triggered comm mode? */
true, /* ABOM: Automatic bus-off management? */
false, /* AWUM: Automatic wakeup mode? */
false, /* NART: No automatic retransmission? */
false, /* RFLM: Receive FIFO locked mode? */
false, /* TXFP: Transmit FIFO priority? */
CAN_BTR_SJW_1TQ,
CAN_BTR_TS1_3TQ,
CAN_BTR_TS2_4TQ,
12)) /* BRP+1: Baud rate prescaler */
{
gpio_set(GPIOA, GPIO8); /* LED0 off */
gpio_set(GPIOB, GPIO4); /* LED1 off */
gpio_set(GPIOC, GPIO15); /* LED2 off */
gpio_clear(GPIOC, GPIO2); /* LED3 on */
gpio_set(GPIOC, GPIO5); /* LED4 off */
/* Die because we failed to initialize. */
while (1)
__asm__("nop");
}
/* CAN filter 0 init. */
can_filter_id_mask_32bit_init(CAN1,
0, /* Filter ID */
0, /* CAN ID */
0, /* CAN ID mask */
0, /* FIFO assignment (here: FIFO0) */
true); /* Enable the filter. */
/* Enable CAN RX interrupt. */
can_enable_irq(CAN1, CAN_IER_FMPIE0);
}
void sys_tick_handler(void)
{
static int temp32 = 0;
static u8 data[8] = {0, 1, 2, 0, 0, 0, 0, 0};
/* We call this handler every 1ms so 1000ms = 1s on/off. */
if (++temp32 != 1000)
return;
temp32 = 0;
/* Transmit CAN frame. */
data[0]++;
if (can_transmit(CAN1,
0, /* (EX/ST)ID: CAN ID */
false, /* IDE: CAN ID extended? */
false, /* RTR: Request transmit? */
8, /* DLC: Data length */
data) == -1)
{
gpio_set(GPIOA, GPIO8); /* LED0 off */
gpio_set(GPIOB, GPIO4); /* LED1 off */
gpio_set(GPIOC, GPIO15); /* LED2 off */
gpio_set(GPIOC, GPIO2); /* LED3 off */
gpio_clear(GPIOC, GPIO5); /* LED4 on */
}
}
void usb_lp_can_rx0_isr(void)
{
u32 id, fmi;
bool ext, rtr;
u8 length, data[8];
can_receive(CAN1, 0, false, &id, &ext, &rtr, &fmi, &length, data);
if (data[0] & 1)
gpio_clear(GPIOA, GPIO8);
else
gpio_set(GPIOA, GPIO8);
if (data[0] & 2)
gpio_clear(GPIOB, GPIO4);
else
gpio_set(GPIOB, GPIO4);
if (data[0] & 4)
gpio_clear(GPIOC, GPIO15);
else
gpio_set(GPIOC, GPIO15);
if (data[0] & 8)
gpio_clear(GPIOC, GPIO2);
else
gpio_set(GPIOC, GPIO2);
can_fifo_release(CAN1, 0);
}
int main(void)
{
rcc_clock_setup_in_hse_12mhz_out_72mhz();
gpio_setup();
can_setup();
systick_setup();
while (1); /* Halt. */
return 0;
}

View File

@@ -0,0 +1,25 @@
##
## This file is part of the libopencm3 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 = fancyblink
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include

View File

@@ -0,0 +1,68 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
* Copyright (C) 2011 Piotr Esden-Tempski <piotr@esden.net>
*
* 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 <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
/* Set STM32 to 72 MHz. */
void clock_setup(void)
{
rcc_clock_setup_in_hse_12mhz_out_72mhz();
/* Enable GPIOB, GPIOC, and AFIO clocks. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
}
void gpio_setup(void)
{
/* Set GPIO13 (in GPIO port C) to 'output push-pull'. */
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
/* Set GPIO4 (in GPIO port B) to 'output push-pull'. */
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO4);
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST;
/* Preconfigure the LEDs. */
gpio_set(GPIOB, GPIO4); /* Switch off LED. */
gpio_clear(GPIOC, GPIO13); /* Switch on LED. */
}
int main(void)
{
int i;
clock_setup();
gpio_setup();
/* Blink the LEDs (PC13 and PB4) on the board. */
while (1) {
gpio_toggle(GPIOC, GPIO13); /* LED on/off */
gpio_toggle(GPIOB, GPIO4); /* LED on/off */
for (i = 0; i < 800000; i++) /* Wait a bit. */
__asm__("nop");
}
return 0;
}

View File

@@ -0,0 +1,32 @@
/*
* This file is part of the libopencm3 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/>.
*/
/* Linker script for Lisa-M (STM32F103RBT6, 128K flash, 20K RAM). */
/* TODO: Chip name and sizes correct? */
/* Define memory regions. */
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
}
/* Include the common ld script. */
INCLUDE libopencm3_stm32f1.ld

View File

@@ -0,0 +1,25 @@
##
## This file is part of the libopencm3 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 = cdcacm
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include

View File

@@ -0,0 +1,7 @@
------------------------------------------------------------------------------
README
------------------------------------------------------------------------------
This example implements a USB CDC-ACM device (aka Virtual Serial Port)
to demonstrate the use of the USB device stack.

View File

@@ -0,0 +1,258 @@
/*
* This file is part of the libopencm3 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 <stdlib.h>
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/cdc.h>
static const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = USB_CLASS_CDC,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = 64,
.idVendor = 0x0483,
.idProduct = 0x5740,
.bcdDevice = 0x0200,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
};
/*
* This notification endpoint isn't implemented. According to CDC spec it's
* optional, but its absence causes a NULL pointer dereference in the
* Linux cdc_acm driver.
*/
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 {
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)) 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 = 1,
},
.acm = {
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
.bmCapabilities = 0,
},
.cdc_union = {
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
.bControlInterface = 0,
.bSubordinateInterface0 = 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 = USB_CLASS_CDC,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
.iInterface = 0,
.endpoint = comm_endp,
.extra = &cdcacm_functional_descriptors,
.extralen = sizeof(cdcacm_functional_descriptors)
}};
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[] = {
"x",
"Black Sphere Technologies",
"CDC-ACM Demo",
"DEMO",
};
static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
u16 *len, void (**complete)(struct usb_setup_data *req))
{
(void)complete;
(void)buf;
switch (req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
/*
* This Linux cdc_acm driver requires this to be implemented
* even though it's optional in the CDC spec, and we don't
* advertise it in the ACM functional descriptor.
*/
char buf[10];
struct usb_cdc_notification *notif = (void*)buf;
/* We echo signals back to host as notification. */
notif->bmRequestType = 0xA1;
notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
notif->wValue = 0;
notif->wIndex = 0;
notif->wLength = 2;
buf[8] = req->wValue & 3;
buf[9] = 0;
// usbd_ep_write_packet(0x83, buf, 10);
return 1;
}
case USB_CDC_REQ_SET_LINE_CODING:
if (*len < sizeof(struct usb_cdc_line_coding))
return 0;
return 1;
}
return 0;
}
static void cdcacm_data_rx_cb(u8 ep)
{
(void)ep;
char buf[64];
int len = usbd_ep_read_packet(0x01, buf, 64);
if (len) {
while (usbd_ep_write_packet(0x82, buf, len) == 0)
;
buf[len] = 0;
}
gpio_toggle(GPIOC, GPIO5);
}
static void cdcacm_set_config(u16 wValue)
{
(void)wValue;
usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
usbd_register_control_callback(
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
cdcacm_control_request);
}
int main(void)
{
int i;
rcc_clock_setup_in_hsi_out_48mhz();
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
gpio_set(GPIOC, GPIO2);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO2);
gpio_set(GPIOC, GPIO5);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO5);
usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
usbd_register_set_config_callback(cdcacm_set_config);
for (i = 0; i < 0x800000; i++)
__asm__("nop");
gpio_clear(GPIOC, GPIO2);
while (1)
usbd_poll();
}

View File

@@ -0,0 +1,56 @@
#! /usr/bin/env python
#
# This file is part of the libopencm3 project.
#
# Copyright (C) 2011 Piotr Esden-Tempski <piotr@esden.net>
#
# 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/>.
#
import serial
import signal
import sys
import time
def signal_handler(signal, frame):
print 'You pressed Ctrl+C!'
ser.close();
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler);
ser = serial.Serial('/dev/cu.usbmodemDEM1', 115200, timeout=0.05);
error = 0
tim = time.time();
cycles = 0
while 1==1:
ser.write("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}");
buf = ser.read(1024);
cycles += 1
if buf != "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}" :
error+=1
print "received " + buf + " errors: " + str(error) + " cycles: " + str(cycles) + " runtime: " + str(time.time() - tim)
#time.sleep(0.1);
ser.close();

View File

@@ -0,0 +1,25 @@
##
## This file is part of the libopencm3 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 = usbdfu
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include

View File

@@ -0,0 +1,7 @@
------------------------------------------------------------------------------
README
------------------------------------------------------------------------------
This example implements a USB Device Firmware Upgrade (DFU) bootloader
to demonstrate the use of the USB device stack.

View File

@@ -0,0 +1,259 @@
/*
* This file is part of the libopencm3 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 <string.h>
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/f1/flash.h>
#include <libopencm3/stm32/f1/scb.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/dfu.h>
#define APP_ADDRESS 0x08002000
/* Commands sent with wBlockNum == 0 as per ST implementation. */
#define CMD_SETADDR 0x21
#define CMD_ERASE 0x41
/* We need a special large control buffer for this device: */
u8 usbd_control_buffer[1024];
static enum dfu_state usbdfu_state = STATE_DFU_IDLE;
static struct {
u8 buf[sizeof(usbd_control_buffer)];
u16 len;
u32 addr;
u16 blocknum;
} prog;
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 = 0xDF11,
.bcdDevice = 0x0200,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
};
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 iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 0,
.bInterfaceClass = 0xFE, /* Device Firmware Upgrade */
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 2,
/* The ST Microelectronics DfuSe application needs this string.
* The format isn't documented... */
.iInterface = 4,
.extra = &dfu_function,
.extralen = sizeof(dfu_function),
};
const struct usb_interface ifaces[] = {{
.num_altsetting = 1,
.altsetting = &iface,
}};
const struct usb_config_descriptor config = {
.bLength = USB_DT_CONFIGURATION_SIZE,
.bDescriptorType = USB_DT_CONFIGURATION,
.wTotalLength = 0,
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = 0,
.bmAttributes = 0xC0,
.bMaxPower = 0x32,
.interface = ifaces,
};
static const char *usb_strings[] = {
"x",
"Black Sphere Technologies",
"DFU Demo",
"DEMO",
/* This string is used by ST Microelectronics' DfuSe utility. */
"@Internal Flash /0x08000000/8*001Ka,56*001Kg",
};
static u8 usbdfu_getstatus(u32 *bwPollTimeout)
{
switch (usbdfu_state) {
case STATE_DFU_DNLOAD_SYNC:
usbdfu_state = STATE_DFU_DNBUSY;
*bwPollTimeout = 100;
return DFU_STATUS_OK;
case STATE_DFU_MANIFEST_SYNC:
/* Device will reset when read is complete. */
usbdfu_state = STATE_DFU_MANIFEST;
return DFU_STATUS_OK;
default:
return DFU_STATUS_OK;
}
}
static void usbdfu_getstatus_complete(struct usb_setup_data *req)
{
int i;
(void)req;
switch (usbdfu_state) {
case STATE_DFU_DNBUSY:
flash_unlock();
if (prog.blocknum == 0) {
switch (prog.buf[0]) {
case CMD_ERASE:
flash_erase_page(*(u32 *)(prog.buf + 1));
case CMD_SETADDR:
prog.addr = *(u32 *)(prog.buf + 1);
}
} else {
u32 baseaddr = prog.addr + ((prog.blocknum - 2) *
dfu_function.wTransferSize);
for (i = 0; i < prog.len; i += 2)
flash_program_half_word(baseaddr + i,
*(u16 *)(prog.buf + i));
}
flash_lock();
/* Jump straight to dfuDNLOAD-IDLE, skipping dfuDNLOAD-SYNC. */
usbdfu_state = STATE_DFU_DNLOAD_IDLE;
return;
case STATE_DFU_MANIFEST:
/* USB device must detach, we just reset... */
scb_reset_system();
return; /* Will never return. */
default:
return;
}
}
static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
u16 *len, void (**complete)(struct usb_setup_data *req))
{
if ((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request. */
switch (req->bRequest) {
case DFU_DNLOAD:
if ((len == NULL) || (*len == 0)) {
usbdfu_state = STATE_DFU_MANIFEST_SYNC;
return 1;
} else {
/* Copy download data for use on GET_STATUS. */
prog.blocknum = req->wValue;
prog.len = *len;
memcpy(prog.buf, *buf, *len);
usbdfu_state = STATE_DFU_DNLOAD_SYNC;
return 1;
}
case DFU_CLRSTATUS:
/* Clear error and return to dfuIDLE. */
if (usbdfu_state == STATE_DFU_ERROR)
usbdfu_state = STATE_DFU_IDLE;
return 1;
case DFU_ABORT:
/* Abort returns to dfuIDLE state. */
usbdfu_state = STATE_DFU_IDLE;
return 1;
case DFU_UPLOAD:
/* Upload not supported for now. */
return 0;
case DFU_GETSTATUS: {
u32 bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
(*buf)[0] = usbdfu_getstatus(&bwPollTimeout);
(*buf)[1] = bwPollTimeout & 0xFF;
(*buf)[2] = (bwPollTimeout >> 8) & 0xFF;
(*buf)[3] = (bwPollTimeout >> 16) & 0xFF;
(*buf)[4] = usbdfu_state;
(*buf)[5] = 0; /* iString not used here */
*len = 6;
*complete = usbdfu_getstatus_complete;
return 1;
}
case DFU_GETSTATE:
/* Return state with no state transision. */
*buf[0] = usbdfu_state;
*len = 1;
return 1;
}
return 0;
}
int main(void)
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
if (!gpio_get(GPIOA, GPIO10)) {
/* Boot the application if it's valid. */
if ((*(volatile u32 *)APP_ADDRESS & 0x2FFE0000) == 0x20000000) {
/* Set vector table base address. */
SCB_VTOR = APP_ADDRESS & 0xFFFF;
/* Initialise master stack pointer. */
asm volatile("msr msp, %0"::"g"
(*(volatile u32 *)APP_ADDRESS));
/* Jump to application. */
(*(void (**)())(APP_ADDRESS + 4))();
}
}
rcc_clock_setup_in_hsi_out_48mhz();
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
gpio_set(GPIOC, GPIO2);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO2);
usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
usbd_register_control_callback(
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
usbdfu_control_request);
gpio_clear(GPIOC, GPIO2);
while (1)
usbd_poll();
}

View File

@@ -0,0 +1,25 @@
##
## This file is part of the libopencm3 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
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include

View File

@@ -0,0 +1,7 @@
------------------------------------------------------------------------------
README
------------------------------------------------------------------------------
This example implements a USB Human Interface Device (HID)
to demonstrate the use of the USB device stack.

View File

@@ -0,0 +1,38 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2011 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 __ADXL345_H
#define __ADXL345_H
/* Register addresses */
#define ADXL345_DEVID 0x00
#define ADXL345_POWER_CTL 0x2D
#define ADXL345_DATA_FORMAT 0x31
#define ADXL345_DATAX0 0x32
#define ADXL345_DATAX1 0x33
#define ADXL345_DATAY0 0x34
#define ADXL345_DATAY1 0x35
#define ADXL345_DATAZ0 0x36
#define ADXL345_DATAZ1 0x37
#define ADXL345_POWER_CTL_MEASURE (1 << 3)
#define ADXL345_DATA_FORMAT_LALIGN (1 << 2)
#endif

View File

@@ -0,0 +1,361 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
* Copyright (C) 2011 Piotr Esden-Tempski <piotr@esden.net>
*
* 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 <stdlib.h>
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/systick.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/otg_fs.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/hid.h>
#include "adxl345.h"
/* Define this to include the DFU APP interface. */
#define INCLUDE_DFU_INTERFACE
#ifdef INCLUDE_DFU_INTERFACE
#include <libopencm3/stm32/f1/scb.h>
#include <libopencm3/usb/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 {
u8 bReportDescriptorType;
u16 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 = 0x02,
};
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_request(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_request(struct usb_setup_data *req, u8 **buf, u16 *len,
void (**complete)(struct usb_setup_data *req))
{
(void)buf;
(void)len;
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_callback(
USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
hid_control_request);
#ifdef INCLUDE_DFU_INTERFACE
usbd_register_control_callback(
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
dfu_control_request);
#endif
systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
systick_set_reload(100000);
systick_interrupt_enable();
systick_counter_enable();
}
static u8 spi_readwrite(u32 spi, u8 data)
{
while (SPI_SR(spi) & SPI_SR_BSY)
;
SPI_DR(spi) = data;
while (!(SPI_SR(spi) & SPI_SR_RXNE))
;
return SPI_DR(spi);
}
static u8 accel_read(u8 addr)
{
u8 ret;
gpio_clear(GPIOB, GPIO12);
spi_readwrite(SPI2, addr | 0x80);
ret = spi_readwrite(SPI2, 0);
gpio_set(GPIOB, GPIO12);
return ret;
}
static void accel_write(u8 addr, u8 data)
{
gpio_clear(GPIOB, GPIO12);
spi_readwrite(SPI2, addr);
spi_readwrite(SPI2, data);
gpio_set(GPIOB, GPIO12);
}
static void accel_get(s16 *x, s16 *y, s16 *z)
{
if (x)
*x = accel_read(ADXL345_DATAX0) |
(accel_read(ADXL345_DATAX1) << 8);
if (y)
*y = accel_read(ADXL345_DATAY0) |
(accel_read(ADXL345_DATAY1) << 8);
if (z)
*z = accel_read(ADXL345_DATAZ0) |
(accel_read(ADXL345_DATAZ1) << 8);
}
int main(void)
{
int i;
rcc_clock_setup_in_hse_12mhz_out_72mhz();
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_IOPCEN);
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_SPI2EN);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
/* Configure SPI2: PB13(SCK), PB14(MISO), PB15(MOSI). */
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_10_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
GPIO_SPI2_SCK | GPIO_SPI2_MOSI);
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
GPIO_SPI2_MISO);
/* Enable CS pin on PB12. */
gpio_set(GPIOB, GPIO12);
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_10_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
/* Force to SPI mode. This should be default after reset! */
SPI2_I2SCFGR = 0;
spi_init_master(SPI2,
SPI_CR1_BAUDRATE_FPCLK_DIV_256,
SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE,
SPI_CR1_CPHA_CLK_TRANSITION_2,
SPI_CR1_DFF_8BIT,
SPI_CR1_MSBFIRST);
/* Ignore the stupid NSS pin. */
spi_enable_software_slave_management(SPI2);
spi_set_nss_high(SPI2);
spi_enable(SPI2);
(void)accel_read(ADXL345_DEVID);
accel_write(ADXL345_POWER_CTL, ADXL345_POWER_CTL_MEASURE);
accel_write(ADXL345_DATA_FORMAT, ADXL345_DATA_FORMAT_LALIGN);
/* USB_DETECT as input. */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO8);
/* Green LED off, as output. */
gpio_set(GPIOC, GPIO2);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO2);
usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
usbd_register_set_config_callback(hid_set_config);
/* Delay some seconds to show that pull-up switch works. */
for (i = 0; i < 0x800000; i++)
__asm__("nop");
/* Wait for USB Vbus. */
while (gpio_get(GPIOA, GPIO8) == 0)
__asm__("nop");
/* Green LED on, connect USB. */
gpio_clear(GPIOC, GPIO2);
// OTG_FS_GCCFG &= ~OTG_FS_GCCFG_VBUSBSEN;
while (1)
usbd_poll();
}
void sys_tick_handler(void)
{
s16 x, y;
u8 buf[4] = {0, 0, 0, 0};
accel_get(&x, &y, NULL);
buf[1] = x >> 9;
buf[2] = y >> 9;
usbd_ep_write_packet(0x81, buf, 4);
}