diff --git a/src/eis_shield/ad5272.c b/src/eis_shield/ad5272.c new file mode 100644 index 0000000000000000000000000000000000000000..90887e2c08ca02cbd20f23ab49a6d613a73ea3ef --- /dev/null +++ b/src/eis_shield/ad5272.c @@ -0,0 +1,116 @@ +// +// AD5272.c +// dstat-firmware +// +// Created by Michael Dryden on 2017-02-18. +// Copyright © 2017 Michael Dryden. All rights reserved. +// + +#include +#include + +#include "ad5272.h" +#include "../config/dstat_config.h" + +#define AD5272_TWI EXT_TWI0 +#define AD5272_ADDR 0b0101110 + +#define WRITE_MASK 0x3FFF // First two bits 0 +#define CMD_MASK 0x3c00 // Next 4 bits +#define DATA_MASK 0x03FF // Last 10 bits +#define CTRL_MASK 0x0007 // Last 3 bits + +// Operations +#define OP_WRITE_RDAC 0x0400 +#define OP_READ_RDAC 0x0800 +#define OP_BURN_RDAC 0x0C00 +#define OP_RESET 0x1000 +#define OP_READ_TP_ADDR 0x1400 +#define OP_READ_TP_LAST 0x1800 +#define OP_WRITE_CTRL 0x1C00 +#define OP_READ_CTRL 0x2000 +#define OP_SHUTDOWN 0x2400 + +// CTRL register bitmasks +#define CTRL_50TP 1 +#define CTRL_RDAC_WP 1 << 1 +#define CTRL_PERFORM 1 << 2 +#define CTRL_50TP_SUCC 1 << 3 + +static uint16_t read(uint16_t address); +static void write(uint16_t input); + +static uint16_t read(uint16_t address) { + /** + * Reads out shift register + * + * @param address Address to read out + * @return Contents of shift register + */ + twi_package_t twi_pack; + + uint16_t buffer; + + union{ + uint8_t uint8[2]; + uint16_t uint16; + } input_buffer; + + input_buffer.uint16 = address; + + twi_pack.addr[0] = input_buffer.uint8[1]; + twi_pack.addr[1] = input_buffer.uint8[0]; + twi_pack.addr_length = 2; + twi_pack.buffer = &buffer; + twi_pack.chip = AD5272_ADDR; + twi_pack.no_wait = false; + twi_pack.length = 2; + + twi_master_read(&AD5272_TWI, &twi_pack); + + return swap16(buffer); +} + +static void write(uint16_t input) { + /** + * Writes to shift register + * + * @param input Contents of shift register + */ + twi_package_t twi_pack; + + uint16_t swapped = swap16(input); + + twi_pack.addr[0] = 0; + twi_pack.addr_length = 0; + twi_pack.buffer = &swapped; + twi_pack.chip = AD5272_ADDR; + twi_pack.no_wait = false; + twi_pack.length = 2; + + twi_master_write(&AD5272_TWI, &twi_pack); + if(twi_master_write(&AD5272_TWI, &twi_pack) != TWI_SUCCESS) + printf("#ERR: AD5272 TWI write fail\r\n"); + + return; +} + +void ad5272_init(void) { + /** + * Enables RDAC writes + */ + + write(OP_WRITE_CTRL | CTRL_RDAC_WP); + printf("#INFO: AD5272: RDAC writes enabled\r\n"); +} + +void ad5272_write_rdac(uint16_t input) { + /** + * Writes to shift register + * + * @param input Contents of shift register + */ + input = OP_WRITE_RDAC | (input & DATA_MASK); + write(input); +// printf("#DBG RDAC: %u\r\n", read(OP_READ_RDAC) & DATA_MASK); +} diff --git a/src/eis_shield/ad5272.h b/src/eis_shield/ad5272.h new file mode 100644 index 0000000000000000000000000000000000000000..2202c9e6fce3b797a9174af2e608841f8eac2fd9 --- /dev/null +++ b/src/eis_shield/ad5272.h @@ -0,0 +1,17 @@ +// +// ad5272.h +// dstat-firmware +// +// Created by Michael Dryden on 2017-02-21. +// Copyright © 2017 Michael Dryden. All rights reserved. +// + +#ifndef ad5272_h +#define ad5272_h + +#include + +void ad5272_init(void); +void ad5272_write_rdac(uint16_t input); + +#endif /* ad5272_h */ diff --git a/src/eis_shield/ds4550.c b/src/eis_shield/ds4550.c new file mode 100644 index 0000000000000000000000000000000000000000..52e4982303ccec35d54e04f74421c84f79affd48 --- /dev/null +++ b/src/eis_shield/ds4550.c @@ -0,0 +1,171 @@ +// +// ds4550.c +// dstat-firmware +// +// Created by Michael Dryden on 2017-02-18. +// Copyright © 2017 Michael Dryden. All rights reserved. +// + +#include +#include + +#include "ds4550.h" +#include "../config/dstat_config.h" + +#define DS4550_TWI EXT_TWI0 + +#define DS4550_ADDR 0b1010000 + +// Memory Addresses +#define EEPROM_USER 0x0 +#define EEPROM_USER_SIZE 0x3F +#define PULLUP_0 0xF0 +#define PULLUP_1 0xF1 +#define IO_CTRL_0 0xF2 +#define IO_CTRL_1 0xF3 +#define CONFIG 0xF4 +#define EEPROM_S_USER 0xF5 +#define EEPROM_S_USER_SIZE 0x02 +#define IO_STATUS_0 0xF8 +#define IO_STATUS_1 0xF9 +#define SRAM_USER 0xFA +#define SRAM_USER_SIZE 0x5 + +static uint8_t read_byte(uint8_t address); +static void read_block(uint8_t address, uint8_t length, uint8_t* buffer); +static void write_byte(uint8_t address, uint8_t value); +static void write_block(uint8_t address, uint8_t length, uint8_t* buffer); + +static uint8_t read_byte(uint8_t address) { + /** + * Reads one byte from AD5933 + * + * @param address Address on AD5933 + * @return Value read. + */ + uint8_t value; + + read_block(address, 1, (uint8_t*)&value); + + return value; +} + +static void read_block(uint8_t address, uint8_t length, uint8_t* buffer) { + /** + * Reads a block of data + * + * @param address Start address on DS4550 + * @param length number of bytes to read. + * @param buffer pointer to buffer to store result + */ + twi_package_t twi_pack; + + twi_pack.addr[0] = address; + twi_pack.addr_length = 1; + twi_pack.buffer = buffer; + twi_pack.chip = DS4550_ADDR; + twi_pack.no_wait = false; + twi_pack.length = length; + + twi_master_read(&DS4550_TWI, &twi_pack); + return; +} + + +static void write_byte(uint8_t address, uint8_t value) { + /** + * Writes one byte to AD5933. + * + * @param address Address on AD5933 + * @param Value to send. + */ + write_block(address, 1, &value); +} + +static void write_block(uint8_t address, uint8_t length, uint8_t* buffer) { + /** + * Writes a block of data + * + * @param address Start address on DS4550 + * @param length number of bytes to write. + * @param buffer pointer to buffer to write + */ + twi_package_t twi_pack; + + twi_pack.addr[0] = address; + twi_pack.addr_length = 1; + twi_pack.buffer = buffer; + twi_pack.chip = DS4550_ADDR; + twi_pack.no_wait = false; + twi_pack.length = length; + + if(twi_master_write(&DS4550_TWI, &twi_pack) != TWI_SUCCESS) + printf("#ERR: DS4550: TWI write fail\r\n"); +} + +void ds4550_set_pin(uint8_t pin, uint8_t state) { + uint16_t current; + read_block(PULLUP_0, 2, (uint8_t*)¤t); + + uint16_t output = (1 << pin); + + if (!state) { + current &= ~output; + } + else { + current |= output; + } + + write_block(PULLUP_0, 2, (uint8_t*)¤t); +} + +void ds4550_set_pins(uint16_t pins, uint16_t pin_mask) { + uint16_t current; + read_block(PULLUP_0, 2, (uint8_t*)¤t); + + pins &= pin_mask; // Make sure pins doesn't have extra 1s + current &= ~pin_mask; // Clear where pin_mask is 1 + + current |= pins; + write_block(PULLUP_0, 2, (uint8_t*)¤t); +} + +uint16_t ds4550_get_pins(void) { + uint16_t current; + read_block(PULLUP_0, 2, (uint8_t*)¤t); + + return current; +} + +void ds4550_set_eeprom(uint8_t on) { + /** + * Enables or disables persistent pin state. + * + * @param on Enables if true, disables if false. + */ + + uint8_t current = read_byte(CONFIG); + + if (on) { + write_byte(CONFIG, current & 0b11111110); // LSB=0 is EEPROM enabled + printf("#INFO: DS4550: EEPROM enabled\r\n"); + } + else { + write_byte(CONFIG, current | 0b00000001); // LSB=1 is EEPROM disabled + printf("#INFO: DS4550: EEPROM disabled\r\n"); + } +} + + +void ds4550_init(void) { + /** + * Checks to make sure pin defaults are all 0, then disables EEPROM writes. + */ + + if ((ds4550_get_pins() & 0x01FF) != 0) { + ds4550_set_eeprom(1); + ds4550_set_pins(0x01FF, 0x01FF); + } + + ds4550_set_eeprom(0); +} diff --git a/src/eis_shield/ds4550.h b/src/eis_shield/ds4550.h new file mode 100644 index 0000000000000000000000000000000000000000..a8031a318d534e1ac9b5b0daada89bd4d9e0f3e4 --- /dev/null +++ b/src/eis_shield/ds4550.h @@ -0,0 +1,21 @@ +// +// ds4550.h +// dstat-firmware +// +// Created by Michael Dryden on 2017-02-18. +// Copyright © 2017 Michael Dryden. All rights reserved. +// + +#ifndef ds4550_h +#define ds4550_h + +#include + +void ds4550_set_pin(uint8_t pin, uint8_t state); +void ds4550_set_pins(uint16_t pins, uint16_t pin_mask); +uint16_t ds4550_get_pins(void); +void ds4550_set_eeprom(uint8_t on); +void ds4550_init(void); + + +#endif /* ds4550_h */ diff --git a/src/experiment.c b/src/experiment.c index d2cda9f99de0813f94f784d3205de3a031bd7694..714be02846f26da55cc95aeda8b6e0df9595d5a4 100644 --- a/src/experiment.c +++ b/src/experiment.c @@ -21,6 +21,8 @@ #include "config/conf_board.h" #include "shutter.h" #include "ad5933.h" +#include "eis_shield/ds4550.h" +#include "eis_shield/ad5272.h" // setting the digital outputs for the mux, relay, and chip select. #define MUX0 IOPORT_CREATE_PIN (PORTF, 0) diff --git a/src/experiment.h b/src/experiment.h index 67c1801e553295fea271d316824d739fda7427cd..10648dbcb8e71188329ea471d6dddbf5cc01e14f 100644 --- a/src/experiment.h +++ b/src/experiment.h @@ -9,7 +9,6 @@ #ifndef EXPERIMENT_H_ #define EXPERIMENT_H_ -#include "conf_experiment.h" #include "ads1255.h" #include "max5443.h" @@ -105,4 +104,4 @@ void ca_experiment(uint16_t steps, uint16_t step_dac[], uint16_t step_seconds[]) void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_height, uint16_t frequency, uint16_t scans); void dpv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_height, uint16_t pulse_period, uint16_t pulse_width); -#endif /* EXPERIMENT_H_ */ \ No newline at end of file +#endif /* EXPERIMENT_H_ */ diff --git a/src/main.c b/src/main.c index 49ef95b719a7e169cc4bd4d00008ed679da8c65a..8eeab7cedbaeba78a545aaf9511d1b23232268ee 100644 --- a/src/main.c +++ b/src/main.c @@ -15,6 +15,7 @@ #include #include "conf_board.h" #include "ext_twi.h" +#include "eis_shield/ds4550.h" //Internal function declarations int8_t command_handler(char command); @@ -121,6 +122,8 @@ int main(void){ udc_attach(); stdio_usb_enable(); + ds4550_init(); + program_loop: #if BOARD_VER_MAJOR >= 1 && BOARD_VER_MINOR >= 2 && BOARD_VER_MICRO >=3 ioport_set_pin_level(LED1, 1);