summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfishsoupisgood <github@madingley.org>2020-06-14 10:55:07 +0100
committerfishsoupisgood <github@madingley.org>2020-06-14 10:55:07 +0100
commit0060468326b7ab0cd07d0d80a84118e7c5bcf348 (patch)
tree8be8ad7b1cb23be4765b9d94a7b8fcefa4d67e27
parentdbc21c1e5dfd95248fe2cd7da6d96c92bdbb97a4 (diff)
downloadrobs_speedo-0060468326b7ab0cd07d0d80a84118e7c5bcf348.tar.gz
robs_speedo-0060468326b7ab0cd07d0d80a84118e7c5bcf348.tar.bz2
robs_speedo-0060468326b7ab0cd07d0d80a84118e7c5bcf348.zip
add tacho
-rw-r--r--app/Makefile2
-rw-r--r--app/i2c_hw.c28
-rw-r--r--app/led.c13
-rw-r--r--app/main.c34
-rw-r--r--app/pins.h55
-rw-r--r--app/project.h14
-rw-r--r--app/prototypes.h4
-rw-r--r--app/tacho.c64
-rw-r--r--app/tacho.h6
-rw-r--r--app/usart.c19
10 files changed, 200 insertions, 39 deletions
diff --git a/app/Makefile b/app/Makefile
index 5bba29c..1a6088a 100644
--- a/app/Makefile
+++ b/app/Makefile
@@ -23,7 +23,7 @@ PROG=speedo
V=1
default: ${PROG}.elf
-CSRCS=main.c led.c i2c.c usart.c ring.c ticker.c oled.c i2c_hw.c font8x8.c font8x16.c
+CSRCS=main.c led.c i2c.c usart.c ring.c ticker.c oled.c i2c_hw.c font8x8.c font8x16.c tacho.c
HSRCS=i2c.h oled.h project.h ring.h
BINARY = ${PROG}
diff --git a/app/i2c_hw.c b/app/i2c_hw.c
index d7989a9..7fc901e 100644
--- a/app/i2c_hw.c
+++ b/app/i2c_hw.c
@@ -5,6 +5,8 @@
#define SCL GPIO6
#define SDA GPIO7
+#define SCL_PORT GPIOB
+#define SDA_PORT GPIOB
void
i2c_clear_start (uint32_t i2c)
@@ -121,33 +123,31 @@ i2cp_reset_sm (void)
{
int i;
- gpio_set_mode (GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
- GPIO_CNF_OUTPUT_PUSHPULL, GPIO_I2C1_SCL | GPIO_I2C1_SDA);
+ MAP_OUTPUT_PP(SCL);
+ MAP_OUTPUT_PP(SDA);
- gpio_set (GPIOB, GPIO_I2C1_SDA);
- gpio_set (GPIOB, GPIO_I2C1_SCL);
+ SET(SDA);
+ SET(SCL);
delay_us (10);
- gpio_clear (GPIOB, GPIO_I2C1_SDA);
+ CLEAR(SDA);
delay_us (10);
- gpio_clear (GPIOB, GPIO_I2C1_SCL);
+ CLEAR(SCL);
for (i = 0; i < 9; ++i)
{
delay_us (10);
- gpio_set (GPIOB, GPIO_I2C1_SCL);
+ SET(SCL);
delay_us (10);
- gpio_clear (GPIOB, GPIO_I2C1_SCL);
+ CLEAR(SCL);
delay_us (10);
}
- gpio_set (GPIOB, GPIO_I2C1_SCL);
+ SET(SCL);
delay_us (10);
- gpio_set (GPIOB, GPIO_I2C1_SDA);
+ SET(SDA);
delay_us (10);
- gpio_set_mode (GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
- GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN,
- GPIO_I2C1_SCL | GPIO_I2C1_SDA);
-
+ MAP_AF_OD(SCL);
+ MAP_AF_OD(SDA);
}
diff --git a/app/led.c b/app/led.c
index 7d8303d..a6bd8ea 100644
--- a/app/led.c
+++ b/app/led.c
@@ -1,26 +1,31 @@
#include "project.h"
+#define LED GPIO13
+#define LED_PORT GPIOC
+
static int led = 0;
void
led_init (void)
{
- gpio_set_mode (GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
- GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
+ MAP_OUTPUT_OD(LED);
+ SET(LED);
+
}
void
led_clear (void)
{
- gpio_set (GPIOC, GPIO13);
+ SET(LED);
+ led =0;
}
void
led_set (void)
{
- gpio_clear (GPIOC, GPIO13);
+ CLEAR(LED);
led = 200;
}
diff --git a/app/main.c b/app/main.c
index c40b571..ee0dd40 100644
--- a/app/main.c
+++ b/app/main.c
@@ -1,5 +1,7 @@
#include "project.h"
+#define WIGGLE GPIO4
+#define WIGGLE_PORT GPIOB
int
main (void)
@@ -18,12 +20,16 @@ main (void)
rcc_periph_clock_enable (RCC_AFIO);
- /*Adjust interrupt priorities so that uarts trump timer */
+ /*Adjust interrupt priorities so that taco trumps uarts trumps timer trumps dma */
+ nvic_set_priority (TACHO_IRQ,0x20);
nvic_set_priority (NVIC_USART1_IRQ, 0x40);
- nvic_set_priority (NVIC_USART2_IRQ, 0x40);
- nvic_set_priority (NVIC_USART3_IRQ, 0x40);
- nvic_set_priority (NVIC_SYSTICK_IRQ, 0xff);
+ nvic_set_priority (NVIC_SYSTICK_IRQ, 0x60);
+ nvic_set_priority (NVIC_DMA1_CHANNEL6_IRQ, 0x80);
+ /* Claw some pins pack*/
+ gpio_primary_remap (AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, 0);
+
+ dwt_enable_cycle_counter();
ticker_init ();
@@ -31,32 +37,36 @@ main (void)
led_init ();
usart_init ();
i2cp_init ();
- //i2cb_init();
-#if 0
- //lcd_init ();
- //
-#endif
printf ("Hello world\n");
led_set ();
- //i2cb_scan();
-
oled_init ();
+ tacho_init();
font8x8_put_str ("ABC fish soup!", 0, 0);
+ MAP_OUTPUT_PP(WIGGLE);
+
+
for (;;)
{
char buf[20];
- sprintf(buf,"%8d",cnt++);
+ sprintf(buf,"%6u rpm",(unsigned) raw_tacho);
font8x16_put_str (buf, 30, 8);
+ sprintf(buf,"%8d",cnt++);
font8x8_put_str (buf, 0, 24);
+
+ if (cnt&1)
+ SET(WIGGLE);
+ else
+ CLEAR(WIGGLE);
+
}
return 0;
diff --git a/app/pins.h b/app/pins.h
new file mode 100644
index 0000000..a29e48f
--- /dev/null
+++ b/app/pins.h
@@ -0,0 +1,55 @@
+#ifndef _PINS_H_
+#define _PINS_H_
+
+/* st seem to change these with every chip revision */
+
+#define MAP_AF_PP(a) do { \
+ gpio_set_mode( a ## _PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, a ); \
+ } while (0)
+
+#define MAP_AF(a) MAP_AF_PP(a)
+
+/* STM32F1 doesn't have AF pull up, but also doesn't disconnect af inputs so just use regular pull up */
+#define MAP_AF_PU(a) do { \
+ gpio_set_mode( a ## _PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, a); \
+ gpio_set( a ## _PORT, a); \
+ } while (0)
+
+#define MAP_AF_OD(a) do { \
+ gpio_set_mode( a ## _PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, a ); \
+ } while (0)
+
+
+#define MAP_OUTPUT_PP(a) do { \
+ gpio_set_mode( a ## _PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, a ); \
+ } while (0)
+
+
+#define MAP_OUTPUT_OD(a) do { \
+ gpio_set_mode( a ## _PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, a ); \
+ } while (0)
+
+
+/* STM32F1 madly uses the output register to drive the other end of the resistor, so pull up */
+/* requires us to write a 1 there */
+
+#define MAP_INPUT_PU(a) do { \
+ gpio_set_mode( a ## _PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, a); \
+ gpio_set( a ## _PORT, a); \
+ } while (0)
+
+
+#define MAP_INPUT(a) do { \
+ gpio_set_mode( a ## _PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, a); \
+ } while (0)
+
+#define MAP_ANALOG(a) do { \
+ gpio_set_mode( a ## _PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, a); \
+ } while (0)
+
+
+#define CLEAR(a) gpio_clear( a ## _PORT, a)
+#define SET(a) gpio_set( a ## _PORT, a)
+#define GET(a) gpio_get( a ## _PORT, a)
+
+#endif
diff --git a/app/project.h b/app/project.h
index a9cb707..e2e10c7 100644
--- a/app/project.h
+++ b/app/project.h
@@ -7,19 +7,31 @@
#include <libopencm3/stm32/dma.h>
#include <libopencm3/stm32/i2c.h>
#include <libopencm3/stm32/adc.h>
+#include <libopencm3/stm32/exti.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/cm3/cortex.h>
+#include <libopencm3/cm3/scb.h>
+#include <libopencm3/cm3/dwt.h>
#include <stdio.h>
#include <errno.h>
+#include "pins.h"
+
#include "i2c.h"
#include "oled.h"
#include "ring.h"
+#include "tacho.h"
+
+
+#define US(a) (72*(a))
+#define MS(a) (US(a) * 1000 )
+#define HZ(a) (MS(a) * 1000)
-#include "prototypes.h"
#define T do { printf("%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__); } while (0)
+
+#include "prototypes.h"
diff --git a/app/prototypes.h b/app/prototypes.h
index 359c826..19b92f0 100644
--- a/app/prototypes.h
+++ b/app/prototypes.h
@@ -66,3 +66,7 @@ extern void font8x8_put_str(char *str, unsigned x, unsigned y);
/* font8x16.c */
extern void font8x16_put_ch(unsigned ch, unsigned x, unsigned y);
extern void font8x16_put_str(char *str, unsigned x, unsigned y);
+/* tacho.c */
+extern uint32_t raw_tacho;
+extern void exit3_isr(void);
+extern void tacho_init(void);
diff --git a/app/tacho.c b/app/tacho.c
new file mode 100644
index 0000000..35331da
--- /dev/null
+++ b/app/tacho.c
@@ -0,0 +1,64 @@
+#include "project.h"
+
+#define SPURIOUS MS(10) /*Anything faster than 6000rpm is a false trigger */
+
+
+
+uint32_t raw_tacho;
+
+static uint32_t
+cycle_diff (uint32_t a, uint32_t b)
+{
+ return b - a;
+}
+
+
+
+void exti3_isr (void)
+{
+uint32_t now, diff;
+static uint32_t last_edge;
+
+if (!( EXTI_PR & TACHO)) return;
+
+EXTI_PR=TACHO;
+
+now=dwt_read_cycle_counter();
+
+diff= cycle_diff(last_edge,now);
+
+if (diff < SPURIOUS) return;
+
+last_edge=now;
+
+
+/* Want RPM, diff is in units of 1/72 us */
+
+if (!diff) return;
+
+/* uint32_t is able to express 60s in clock ticks, so divide everything by 2 */
+
+diff >>=1;
+
+
+
+raw_tacho =(US ((60*1000000)/2))/diff;
+
+}
+
+
+void tacho_init (void)
+{
+ MAP_INPUT_PU (TACHO);
+
+ exti_select_source (TACHO,TACHO_PORT);
+ exti_set_trigger (TACHO, EXTI_TRIGGER_FALLING);
+ exti_enable_request (TACHO);
+ exti_reset_request (TACHO);
+
+ nvic_enable_irq (TACHO_IRQ);
+
+}
+
+
+
diff --git a/app/tacho.h b/app/tacho.h
new file mode 100644
index 0000000..5388cf0
--- /dev/null
+++ b/app/tacho.h
@@ -0,0 +1,6 @@
+
+#define TACHO_IRQ NVIC_EXTI3_IRQ
+#define TACHO GPIO3
+#define TACHO_PORT GPIOB
+#define TACHO_ISR exit3_isr
+
diff --git a/app/usart.c b/app/usart.c
index 177d165..29a2978 100644
--- a/app/usart.c
+++ b/app/usart.c
@@ -1,7 +1,13 @@
#include "project.h"
#define BUFFER_SIZE 256
-#define BIG_BUFFER_SIZE 600
+
+
+#define USART1_TX GPIO_USART1_TX
+#define USART1_TX_PORT GPIOA
+#define USART1_RX GPIO_USART1_RX
+#define USART1_RX_PORT GPIOA
+
ring_t rx1_ring;
static uint8_t rx1_ring_buf[BUFFER_SIZE];
@@ -98,11 +104,10 @@ usart_init (void)
/* Enable the USART1,2 interrupt. */
nvic_enable_irq (NVIC_USART1_IRQ);
- /* Map pins, and set usart2 to have pull ups */
- gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
- GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
- gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
- GPIO_USART1_RX);
+ /* Map pins, and usart1 to have pull ups */
+ MAP_AF_PP(USART1_TX);
+ MAP_INPUT_PU(USART1_RX);
+
/* Setup UART1 parameters. */
usart_set_baudrate (USART1, 115200);
@@ -113,7 +118,7 @@ usart_init (void)
usart_set_mode (USART1, USART_MODE_TX_RX);
- /* Enable USART1,2 Receive interrupt. */
+ /* Enable USART1 Receive interrupt. */
USART_CR1 (USART1) |= USART_CR1_RXNEIE;
/* Finally enable the USARTs. */