aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2010-08-07 20:29:37 -0400
committerbnewbold <bnewbold@robocracy.org>2010-08-07 20:29:37 -0400
commit7b391d7f76a2d56242420c560d65f00a60f78682 (patch)
tree8fb56b1ba9fb8fe557a5159407275ecfdd764e72
parent314846bee32479f8fd6aae46c508fdc7ff8e0a95 (diff)
downloadlibrambutan-7b391d7f76a2d56242420c560d65f00a60f78682.tar.gz
librambutan-7b391d7f76a2d56242420c560d65f00a60f78682.zip
basic working dac implementation
-rw-r--r--examples/test-dac.cpp53
-rw-r--r--libmaple/dac.c67
-rw-r--r--libmaple/dac.h108
-rw-r--r--libmaple/rcc.h3
-rw-r--r--libmaple/rules.mk1
-rw-r--r--notes/dac.txt32
6 files changed, 264 insertions, 0 deletions
diff --git a/examples/test-dac.cpp b/examples/test-dac.cpp
new file mode 100644
index 0000000..65496f4
--- /dev/null
+++ b/examples/test-dac.cpp
@@ -0,0 +1,53 @@
+
+#include "wirish.h"
+#include "fsmc.h"
+#include "rcc.h"
+#include "gpio.h"
+#include "dac.h"
+
+#define LED_PIN 23 // hack for maple native
+#define DISC_PIN 14 // hack for USB on native
+
+int toggle = 0;
+uint16 count = 0;
+
+void setup() {
+
+ pinMode(LED_PIN, OUTPUT);
+ pinMode(DISC_PIN, OUTPUT);
+ digitalWrite(DISC_PIN,1);
+ digitalWrite(LED_PIN,1);
+
+ Serial1.begin(9600);
+ Serial1.println("Hello World!");
+
+ Serial1.print("Init... ");
+ dac_init();
+ Serial1.println("Done.");
+}
+
+void loop() {
+ digitalWrite(LED_PIN, toggle);
+ toggle ^= 1;
+ delay(100);
+
+ count += 100;
+
+ if(count > 4095) {
+ count = 0;
+ }
+
+ dac_write(1, 2048);
+ dac_write(2, count);
+}
+
+int main(void) {
+ init();
+ setup();
+
+ while (1) {
+ loop();
+ }
+ return 0;
+}
+
diff --git a/libmaple/dac.c b/libmaple/dac.c
new file mode 100644
index 0000000..b9c7d63
--- /dev/null
+++ b/libmaple/dac.c
@@ -0,0 +1,67 @@
+
+/* *****************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2010 Bryan Newbold.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * ****************************************************************************/
+
+#include "libmaple.h"
+#include "rcc.h"
+#include "gpio.h"
+#include "dac.h"
+
+// Only one, so global to this file
+DAC_Map *dac = (DAC_Map*)(DAC_BASE);
+
+// This numbering follows the registers (1-indexed)
+#define DAC_CHA 1
+#define DAC_CHB 2
+
+// Sets up the DAC peripheral
+void dac_init(void) {
+
+ // First turn on the clock
+ rcc_enable_clk_dac();
+
+ // Then setup ANALOG mode on PA4 and PA5
+ gpio_set_mode(GPIOA_BASE, 4, CNF_INPUT_ANALOG);
+ gpio_set_mode(GPIOA_BASE, 5, CNF_INPUT_ANALOG);
+
+ // Then do register stuff.
+ // Default does no triggering, and buffered output, so all good.
+ dac->CR |= DAC_CR_EN1;
+ dac->CR |= DAC_CR_EN2;
+
+}
+
+void dac_write(uint8 chan, uint16 val) {
+
+ switch(chan) {
+ case DAC_CHA:
+ dac->DHR12R1 = 0x0FFF & val;
+ break;
+ case DAC_CHB:
+ dac->DHR12R2 = 0x0FFF & val;
+ break;
+ default:
+ ASSERT(0); // Shouldn't get here
+ }
+}
diff --git a/libmaple/dac.h b/libmaple/dac.h
new file mode 100644
index 0000000..de1fd3f
--- /dev/null
+++ b/libmaple/dac.h
@@ -0,0 +1,108 @@
+/* *****************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2010 Bryan Newbold.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * ****************************************************************************/
+
+/*
+ * See ../notes/dac.txt for more info
+ */
+
+#ifndef _DAC_H_
+#define _DAC_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define DAC_BASE 0x40007400
+
+typedef struct {
+ volatile uint32 CR;
+ volatile uint32 SWTRIGR;
+ volatile uint32 DHR12R1;
+ volatile uint32 DHR12L1;
+ volatile uint32 DHR8R1;
+ volatile uint32 DHR12R2;
+ volatile uint32 DHR12L2;
+ volatile uint32 DHR8R2;
+ volatile uint32 DHR12RD;
+ volatile uint32 DHR12LD;
+ volatile uint32 DHR8RD;
+ volatile uint32 DOR1;
+ volatile uint32 DOR2;
+} DAC_Map;
+
+
+// And here are the register bit ranges
+#define DAC_CR_EN1 BIT(0)
+#define DAC_CR_BOFF1 BIT(1)
+#define DAC_CR_TEN1 BIT(2)
+#define DAC_CR_TSEL1 (BIT(3) | BIT(4) | BIT(5))
+#define DAC_CR_WAVE1 (BIT(6) | BIT(7))
+#define DAC_CR_MAMP1 (BIT(8) | BIT(9) | BIT(10) | BIT(11))
+#define DAC_CR_DMAEN1 BIT(12)
+#define DAC_CR_EN2 BIT(16)
+#define DAC_CR_BOFF2 BIT(17)
+#define DAC_CR_TEN2 BIT(18)
+#define DAC_CR_TSEL2 (BIT(19) | BIT(20) | BIT(21))
+#define DAC_CR_WAVE2 (BIT(22) | BIT(23))
+#define DAC_CR_MAMP2 (BIT(24) | BIT(25) | BIT(26) | BIT(27))
+#define DAC_CR_DMAEN2 BIT(28)
+
+#define DAC_SWTRIGR_SWTRIG1 BIT(0)
+#define DAC_SWTRIGR_SWTRIG2 BIT(1)
+
+#define DAC_DHR12R1_DACC1DHR 0x00000FFF
+
+#define DAC_DHR12L1_DACC1DHR 0x0000FFF0
+
+#define DAC_DHR8R1_DACC1DHR 0x000000FF
+
+#define DAC_DHR12R2_DACC2DHR 0x00000FFF
+
+#define DAC_DHR12L2_DACC2DHR 0x0000FFF0
+
+#define DAC_DHR8R2_DACC2DHR 0x000000FF
+
+#define DAC_DHR12RD_DACC1DHR 0x00000FFF
+#define DAC_DHR12RD_DACC2DHR 0x0FFF0000
+
+#define DAC_DHR12LD_DACC1DHR 0x0000FFF0
+#define DAC_DHR12LD_DACC2DHR 0xFFF00000
+
+#define DAC_DHR8RD_DACC1DHR 0x000000FF
+#define DAC_DHR8RD_DACC2DHR 0x0000FF00
+
+#define DAC_DOR1 0x00000FFF
+
+#define DAC_DOR2 0x00000FFF
+
+
+void dac_init(void);
+void dac_write(uint8 chan, uint16 val);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif
diff --git a/libmaple/rcc.h b/libmaple/rcc.h
index 8ad70e5..2dca151 100644
--- a/libmaple/rcc.h
+++ b/libmaple/rcc.h
@@ -139,6 +139,7 @@ struct rcc_device {
#define RCC_APB1ENR_USART3EN BIT(18)
#define RCC_APB1ENR_SPI2EN BIT(14)
#define RCC_APB1ENR_USB BIT(23)
+#define RCC_APB1ENR_DACEN BIT(29)
/* AHB peripheral clock enable bits */
#define RCC_AHBENR_DMA1EN BIT(0)
@@ -174,6 +175,8 @@ struct rcc_device {
#define rcc_enable_clk_adc1() __set_bits(RCC_APB2ENR, RCC_APB2ENR_ADC1EN)
+#define rcc_enable_clk_dac() __set_bits(RCC_APB1ENR, RCC_APB1ENR_DACEN)
+
#define rcc_reset_adc1() { __set_bits(RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); \
__clear_bits(RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); \
}
diff --git a/libmaple/rules.mk b/libmaple/rules.mk
index db9540a..8428277 100644
--- a/libmaple/rules.mk
+++ b/libmaple/rules.mk
@@ -26,6 +26,7 @@ cSRCS_$(d) := systick.c \
flash.c \
spi.c \
fsmc.c \
+ dac.c \
usb/usb.c \
usb/usb_callbacks.c \
usb/usb_hardware.c \
diff --git a/notes/dac.txt b/notes/dac.txt
new file mode 100644
index 0000000..9df0782
--- /dev/null
+++ b/notes/dac.txt
@@ -0,0 +1,32 @@
+
+DAC notes (for maple native and other "high density" STM32 devices)
+-------------------------------------------------------------------------------
+There is an ST application note for the DACs; it provides a lot of context but
+doesn't help setup the peripheral very much.
+
+For the first code iteration we'll just use 12-bit right-aligned single writes,
+so use DAC_DHR12Rx
+
+Once data is loaded into the digital registers, there are a number of possible
+triggers to start conversion to analog output: external interrupts, software
+control, and timer events. We'll just use software triggering for now.
+
+There is (obviously) DMA support for DAC output.
+
+There are noise output and triangle wave output features with variable
+amplitude.
+
+There are many additional modes to tigger output to both channels at the same
+time.
+
+Buffering will be enabled by default.
+
+TODO
+-------------------------------------------------------------------------------
+- sine wave demo using Timer interrupts
+- wirish implementation
+- documentation
+- higher performance modes?
+- signal quality testing
+- DMA output
+