aboutsummaryrefslogtreecommitdiffstats
path: root/examples/i2c-mcp4725-dac.cpp
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2012-06-26 18:24:49 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2012-06-26 18:32:57 -0400
commitf005bd3a5c087e3d5559f2858a1e7898a4f92a8d (patch)
tree0701628a68056f7b5f92d5a5af5f281f58e6a71e /examples/i2c-mcp4725-dac.cpp
parent761e059962e8f53f3cceef61d65bf2bf3025319a (diff)
parentc6073e4886da4606679bc3e9d770c9cff9390597 (diff)
downloadlibrambutan-f005bd3a5c087e3d5559f2858a1e7898a4f92a8d.tar.gz
librambutan-f005bd3a5c087e3d5559f2858a1e7898a4f92a8d.zip
Merge branch 'wip-family-support'
Merge the long-lived (too long; future changes like these will need to proceed more incrementally) development branch of libmaple, containing experimental STM32F2 and STM32F1 value line support, into master. This required many changes to the structure of the library. The most important structural reorganizations occurred in: - 954f9e5: moves public headers to include directories - 3efa313: uses "series" instead of "family" - c0d60e3: adds board files to the build system, to make it easier to add new boards - 096d86c: adds build logic for targeting different STM32 series (e.g. STM32F1, STM32F2) This last commit in particular (096d86c) is the basis for the repartitioning of libmaple into portable sections, which work on all supported MCUs, and nonportable sections, which are segregated into separate directories and contain all series-specific code. Moving existing STM32F1-only code into libmaple/stm32f1 and wirish/stm32f1, along with adding equivalents under .../stm32f2 directories, was the principal project of this branch. Important API changes occur in several places. Existing code is still expected to work on STM32F1 targets, but there have been many deprecations. A detailed changelog explaining the situation needs to be prepared. F2 and F1 value line support is not complete; the merge is proceeding prematurely in this respect. We've been getting more libmaple patches from the community lately, and I'm worried that the merge conflicts with the old tree structure will become painful to manage. Conflicts: Makefile Resolved Makefile conflicts manually; this required propagating -Xlinker usage into support/make/target-config.mk. Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
Diffstat (limited to 'examples/i2c-mcp4725-dac.cpp')
-rw-r--r--examples/i2c-mcp4725-dac.cpp145
1 files changed, 145 insertions, 0 deletions
diff --git a/examples/i2c-mcp4725-dac.cpp b/examples/i2c-mcp4725-dac.cpp
new file mode 100644
index 0000000..da9a34e
--- /dev/null
+++ b/examples/i2c-mcp4725-dac.cpp
@@ -0,0 +1,145 @@
+// i2c-mcp4725-dac.cpp
+//
+// Written by Andrew Meyer <ajm@leaflabs.com>
+// Modified by Marti Bolivar <mbolivar@leaflabs.com>
+//
+// Simple program showing how to control an MCP4725 DAC using the
+// libmaple I2C interface. There's an MCP4725 breakout board available
+// on SparkFun:
+//
+// http://www.sparkfun.com/products/8736
+//
+// How to use:
+//
+// 1. Connect the DAC SDA and SCL pins to I2C2, with a pullup
+// resistor (1 KOhm should work) to VCC.
+// 2. Load the sketch and connect to SerialUSB.
+// 3. Press the button.
+//
+// The program then makes sure the DAC is connected properly (during
+// setup()), then has the DAC output a sawtooth wave (with loop()).
+
+#include <wirish/wirish.h>
+#include <libmaple/i2c.h>
+
+#define MCP_ADDR 0x60
+#define MCP_WRITE_DAC 0b01000000
+#define MCP_WRITE_EEPROM 0b01100000
+#define MCP_PD_NORMAL 0b00000000
+#define MCP_PD_1K 0b00000010
+#define MCP_PD_100K 0b00000100
+#define MCP_PD_500K 0b00000110
+
+static uint8 write_msg_data[3];
+static i2c_msg write_msg;
+
+static uint8 read_msg_data[5];
+static i2c_msg read_msg;
+
+/*
+ * DAC control routines
+ */
+
+void mcp_i2c_setup(void) {
+ write_msg.addr = MCP_ADDR;
+ write_msg.flags = 0; // write, 7 bit address
+ write_msg.length = sizeof(write_msg_data);
+ write_msg.xferred = 0;
+ write_msg.data = write_msg_data;
+
+ read_msg.addr = MCP_ADDR;
+ read_msg.flags = I2C_MSG_READ;
+ read_msg.length = sizeof(read_msg_data);
+ read_msg.xferred = 0;
+ read_msg.data = read_msg_data;
+}
+
+void mcp_write_val(uint16 val) {
+ write_msg_data[0] = MCP_WRITE_DAC | MCP_PD_NORMAL;
+ uint16 tmp = val >> 4;
+ write_msg_data[1] = tmp;
+ tmp = (val << 4) & 0x00FF;
+ write_msg_data[2] = tmp;
+
+ i2c_master_xfer(I2C2, &write_msg, 1, 0);
+}
+
+uint16 mcp_read_val() {
+ uint16 tmp = 0;
+
+ i2c_master_xfer(I2C2, &read_msg, 1, 2);
+
+ /* We don't care about the status and EEPROM bytes (0, 3, and 4). */
+ tmp = (read_msg_data[1] << 4);
+ tmp += (read_msg_data[2] >> 4);
+ return tmp;
+}
+
+int mcp_test() {
+ uint16 val;
+ uint16 test_val = 0x0101;
+
+ SerialUSB.println("Testing the MCP4725...");
+ /* Read the value of the register (should be 0x0800 if factory fresh) */
+ val = mcp_read_val();
+ SerialUSB.print("DAC Register = 0x");
+ SerialUSB.println(val, HEX);
+
+ mcp_write_val(test_val);
+ SerialUSB.print("Wrote 0x");
+ SerialUSB.print(test_val, HEX);
+ SerialUSB.println(" to the DAC");
+
+ val = mcp_read_val();
+ SerialUSB.print("DAC Register = 0x");
+ SerialUSB.println(val, HEX);
+
+ if (val != test_val) {
+ SerialUSB.println("ERROR: MCP4725 not responding correctly");
+ return 0;
+ }
+
+ SerialUSB.println("MCP4725 seems to be working");
+ return 1;
+}
+
+/*
+ * setup() and loop()
+ */
+
+void setup() {
+ pinMode(BOARD_BUTTON_PIN, INPUT);
+ i2c_master_enable(I2C2, 0);
+ mcp_i2c_setup();
+
+ waitForButtonPress();
+ ASSERT(mcp_test());
+
+ SerialUSB.println("Starting sawtooth wave");
+}
+
+void loop() {
+ static uint16 dout = 0;
+
+ mcp_write_val(dout);
+
+ dout += 50;
+ if (dout >= 32768) {
+ dout = 0;
+ }
+}
+
+// -- init() and main() -------------------------------------------------------
+
+__attribute__((constructor)) void premain() {
+ init();
+}
+
+int main(void) {
+ setup();
+
+ while (true) {
+ loop();
+ }
+ return 0;
+}