aboutsummaryrefslogtreecommitdiff
path: root/examples/stm32/f1
diff options
context:
space:
mode:
authorGareth McMullin2011-10-31 23:04:36 +1300
committerPiotr Esden-Tempski2011-10-31 14:15:02 -0700
commit97fa5ff815dc2920f8bb675f21cf0cda7588dcaf (patch)
tree94a2f42d85f545cddc0f1c6c2d7a9b11d7803b4d /examples/stm32/f1
parent990109ef4701f863da086571765a8fa00670b99c (diff)
Lisa-M HID example uses accelerometer to move mouse.
Diffstat (limited to 'examples/stm32/f1')
-rw-r--r--examples/stm32/f1/lisa-m/usb_hid/adxl345.h38
-rw-r--r--examples/stm32/f1/lisa-m/usb_hid/usbhid.c85
2 files changed, 115 insertions, 8 deletions
diff --git a/examples/stm32/f1/lisa-m/usb_hid/adxl345.h b/examples/stm32/f1/lisa-m/usb_hid/adxl345.h
new file mode 100644
index 0000000..a9720c4
--- /dev/null
+++ b/examples/stm32/f1/lisa-m/usb_hid/adxl345.h
@@ -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
+
diff --git a/examples/stm32/f1/lisa-m/usb_hid/usbhid.c b/examples/stm32/f1/lisa-m/usb_hid/usbhid.c
index e9b9099..8c02090 100644
--- a/examples/stm32/f1/lisa-m/usb_hid/usbhid.c
+++ b/examples/stm32/f1/lisa-m/usb_hid/usbhid.c
@@ -22,10 +22,13 @@
#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
@@ -91,7 +94,7 @@ const struct usb_endpoint_descriptor hid_endpoint = {
.bEndpointAddress = 0x81,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 4,
- .bInterval = 0x20,
+ .bInterval = 0x02,
};
const struct usb_interface_descriptor hid_iface = {
@@ -238,13 +241,81 @@ static void hid_set_config(u16 wValue)
systick_counter_enable();
}
+static uint8_t spi_readwrite(uint32_t spi, uint8_t data)
+{
+ while(SPI_SR(spi) & SPI_SR_BSY);
+ SPI_DR(spi) = data;
+ while(!(SPI_SR(spi) & SPI_SR_RXNE));
+ return SPI_DR(spi);
+}
+
+static uint8_t accel_read(uint8_t addr)
+{
+ uint8_t 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(uint8_t addr, uint8_t data)
+{
+ gpio_clear(GPIOB, GPIO12);
+ spi_readwrite(SPI2, addr);
+ spi_readwrite(SPI2, data);
+ gpio_set(GPIOB, GPIO12);
+}
+
+static void accel_get(int16_t *x, int16_t *y, int16_t *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)
{
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);
+
+ /* 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);
+
+ uint8_t x = 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,
@@ -275,14 +346,12 @@ int main(void)
void sys_tick_handler(void)
{
- static int x = 0;
- static int dir = 1;
+ int16_t x, y;
u8 buf[4] = {0, 0, 0, 0};
- buf[1] = dir;
- x += dir;
- if(x > 30) dir = -dir;
- if(x < -30) dir = -dir;
+ accel_get(&x, &y, NULL);
+ buf[1] = x >> 9;
+ buf[2] = y >> 9;
usbd_ep_write_packet(0x81, buf, 4);
}