diff options
author | Marti Bolivar <mbolivar@leaflabs.com> | 2012-06-26 18:24:49 -0400 |
---|---|---|
committer | Marti Bolivar <mbolivar@leaflabs.com> | 2012-06-26 18:32:57 -0400 |
commit | f005bd3a5c087e3d5559f2858a1e7898a4f92a8d (patch) | |
tree | 0701628a68056f7b5f92d5a5af5f281f58e6a71e /examples/i2c-mcp4725-dac.cpp | |
parent | 761e059962e8f53f3cceef61d65bf2bf3025319a (diff) | |
parent | c6073e4886da4606679bc3e9d770c9cff9390597 (diff) | |
download | librambutan-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.cpp | 145 |
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; +} |