Skip to content

Commit 237a471

Browse files
committed
Improve documentation for power source instrument
1 parent eb71924 commit 237a471

File tree

2 files changed

+129
-59
lines changed

2 files changed

+129
-59
lines changed

src/instruments/powersource.c

Lines changed: 117 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,54 @@
33
#include "../bus/uart/uart.h"
44
#include "../bus/i2c/i2c.h"
55
#include "../bus/spi/spi.h"
6-
#include "../helpers/delay.h"
7-
#include "../registers/system/pin_manager.h"
86
#include "powersource.h"
97

10-
11-
#ifndef V5_HW
12-
138
/*********/
149
/* Types */
1510
/*********/
1611

17-
/// @brief DAC selection bit.
18-
enum DAC {
19-
DAC_A,
20-
DAC_B
12+
/** @brief Channel selection.
13+
* @details
14+
* V5 hardware has four independent channels:
15+
* 0: PCS
16+
* 1: PV3
17+
* 2: PV2
18+
* 3: PV1
19+
* V6 hardware has two pairs of paired channels:
20+
* 0: PVS1 & PVS3
21+
* 1: PVS2 & PCS
22+
* Paired channels share relative output levels, i.e. if PV1 outputs 5 V
23+
* then PV3 outputs 3.3 V.
24+
*/
25+
enum Channel {
26+
PCS,
27+
PV3,
28+
PV2,
29+
PV1,
30+
NUM_V5_CHANNELS,
31+
PVS1_PVS3 = 0,
32+
PVS2_PCS,
33+
NUM_V6_CHANNELS,
2134
};
2235

23-
/// @brief Output gain selection bit.
36+
/** @brief Output gain selection bit.
37+
* @details
38+
* The gain values are reversed between the MCP4822 (v6) and the
39+
* MCP4728 (v5). Thanks, Microchip!
40+
*/
2441
enum Gain {
42+
#ifndef V5_HW
43+
GAIN_X2,
44+
GAIN_X1,
45+
#else
46+
GAIN_X1,
2547
GAIN_X2,
26-
GAIN_X1
48+
#endif // V5_HW
49+
GAINS
2750
};
51+
int GAINVAL[GAINS] = {[GAIN_X1] = 1, [GAIN_X2] = 2};
52+
53+
#ifndef V5_HW
2854

2955
/// @brief Output shutdown control bit.
3056
enum Output {
@@ -36,19 +62,54 @@ enum Output {
3662
union MCP4822Command {
3763
struct {
3864
uint16_t DATA : 12;
39-
enum Output SHDN : 1;
40-
enum Gain GA : 1;
65+
uint16_t SHDN : 1;
66+
uint16_t GA : 1;
4167
uint16_t : 1;
42-
enum DAC AB : 1;
68+
uint16_t AB : 1;
4369
};
4470
uint16_t reg;
4571
};
4672

73+
#else // V5_HW
74+
75+
/** @brief Output shutdown control bit.
76+
* @details
77+
* Also reversed compared to MCP4822. When not on, DAC output is pulled to
78+
* ground via a 1K, 100K, or 500K resistor.
79+
*/
80+
enum Output {
81+
OUTPUT_ON,
82+
OUTPUT_OFF_1K,
83+
OUTPUT_OFF_100K,
84+
OUTPUT_OFF, // 500K
85+
};
86+
87+
union MCP4728Command {
88+
struct {
89+
uint16_t : 1; // UDAC
90+
uint16_t DAC : 2;
91+
uint16_t CMD : 5;
92+
93+
uint16_t DATA_H : 4;
94+
uint16_t GX : 1;
95+
uint16_t PDSEL : 2;
96+
uint16_t VREF : 1;
97+
98+
uint16_t DATA_L : 8;
99+
};
100+
uint8_t buffer[3];
101+
};
102+
103+
#endif // V5_HW
104+
47105
/********************/
48106
/* Static functions */
49107
/********************/
50108

51-
static bool initialize(void) {
109+
#ifndef V5_HW
110+
111+
static bool initialize(void)
112+
{
52113
const SPI_Config conf = {{{
53114
.PPRE = SPI_SCLK125000 >> 3,
54115
.SPRE = SPI_SCLK125000 & 7,
@@ -64,65 +125,71 @@ static bool initialize(void) {
64125
return SPI_configure(conf);
65126
}
66127

67-
/*********************/
128+
/**
129+
* @brief Convert a V5 pin number to the corresponding pin number for the V6.
130+
* @details See documentation for Channel.
131+
* @param channel
132+
* @return enum Channel
133+
*/
134+
static enum Channel v5_to_v6_channel(enum Channel const channel)
135+
{
136+
return (channel + 1) % 2;
137+
}
138+
139+
/************************/
68140
/* Command functions */
69-
/*********************/
141+
/************************/
70142

71-
response_t POWER_SOURCE_SetPower(void) {
72-
enum DAC const dac = (UART1_Read() + 1) % 2;
73-
uint16_t const voltage = UART1_ReadInt() & 0xFFF;
143+
response_t POWER_SOURCE_SetPower(void)
144+
{
145+
enum Channel const channel = v5_to_v6_channel(UART1_Read() & 0x03);
146+
uint16_t const output = UART1_ReadInt() & 0xFFF;
74147
union MCP4822Command cmd = {{
75-
.DATA = voltage,
148+
.DATA = output,
76149
.SHDN = OUTPUT_ON,
77150
.GA = GAIN_X2,
78-
.AB = dac
151+
.AB = channel,
79152
}};
80153

81154
if(initialize()) {
82155
return (
83156
SPI_exchange_int(SPI_PS, &cmd.reg) ? SUCCESS : FAILED
84157
);
85158
}
86-
87159
return FAILED;
88160
}
89161

90-
#else
91-
92-
union MCP4728Command {
93-
struct {
94-
uint16_t : 1; // UDAC
95-
uint16_t DAC : 2;
96-
uint16_t CMD : 5;
97-
98-
uint16_t DATA_H : 4;
99-
uint16_t GX : 1;
100-
uint16_t PDSEL : 2;
101-
uint16_t VREF : 1;
102-
103-
uint16_t DATA_L : 8;
104-
};
105-
uint8_t buffer[3];
106-
};
162+
#else // V5_HW
107163

108164
response_t POWER_SOURCE_SetPower(void) {
109-
uint8_t const dac = UART1_Read() & 0x03;
110-
uint16_t const voltage = UART1_ReadInt() & 0xFFF;
165+
enum VRef {
166+
VREF_EXTERNAL,
167+
VREF_INTERNAL,
168+
};
169+
enum Command {
170+
SINGLE_WRITE = 0b01011,
171+
};
172+
uint8_t const channel = UART1_Read() & 0x03;
173+
uint16_t const output = UART1_ReadInt() & 0xFFF;
111174
union MCP4728Command cmd = {{
112-
.CMD = 0b01011, // Single write
113-
.DAC = dac,
114-
.VREF = 1, // Internal
115-
.PDSEL = 0, // Normal mode
116-
.GX = 1, // Gain x2
117-
.DATA_L = voltage & 0xFF,
118-
.DATA_H = (voltage >> 8) & 0xF
175+
.CMD = SINGLE_WRITE,
176+
.DAC = channel,
177+
.VREF = VREF_INTERNAL,
178+
.PDSEL = OUTPUT_ON,
179+
.GX = GAIN_X2,
180+
.DATA_L = output & 0xFF,
181+
.DATA_H = output >> 8
119182
}};
120183
I2C_InitializeIfNot(I2C_BAUD_RATE_400KHZ, I2C_ENABLE_INTERRUPTS);
121184

185+
enum MCP4728Address {
186+
ADDRESS = 0x60,
187+
};
188+
122189
return I2C_BulkWrite(
123190
cmd.buffer,
124191
sizeof(cmd.buffer),
125-
MCP4728_I2C_DEVICE_ADDRESS
192+
ADDRESS
126193
);
127194
}
128195

src/instruments/powersource.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
#ifndef POWER_SOURCE_H
22
#define POWER_SOURCE_H
33

4-
#include <xc.h>
5-
6-
#define MCP4728_I2C_DEVICE_ADDRESS 0x60
7-
84
#ifdef __cplusplus
95
extern "C" {
106
#endif /* __cplusplus */
@@ -22,10 +18,18 @@ extern "C" {
2218
* 1 (0b01) - PV3
2319
* 2 (0b10) - PV2
2420
* 3 (0b11) - PV1
25-
* @param voltage uint16
26-
* Integer value between 0 and 3300, corresponding to the channel's
27-
* output voltage with 0 corresponding to the lowest voltage and
28-
* 3300 to the highest.
21+
* @param output uint16
22+
* Channel output level in mV relative to the VDD line (3300 mV). A
23+
* value of 0 produces an output equal to the low end of the channel's
24+
* range; a value of 3300 produces an output equal to the high end of
25+
* the channel's range:
26+
* channel output==0 output==3300
27+
* PV(S)1 -5 V 5 V
28+
* PV(S)2 -3.3 V 3.3 V
29+
* PV(S)3 0 V 3.3 V
30+
* PCS 3.3 mA 0 A
31+
* Note that the direction of the output range for the PCS channel is
32+
* inverted compared to the other channels.
2933
*
3034
* @return SUCCESS, FAILED
3135
*/
@@ -36,4 +40,3 @@ extern "C" {
3640
#endif
3741

3842
#endif /* POWER_SOURCE_H */
39-

0 commit comments

Comments
 (0)