|
|
@@ -11,34 +11,44 @@ |
|
|
|
#include "mode.h"
|
|
|
|
#include "led.h"
|
|
|
|
#include "zoom.h"
|
|
|
|
#include "packet.h"
|
|
|
|
|
|
|
|
int send_data = 0;
|
|
|
|
uint16_t send_adc;
|
|
|
|
uint16_t send_dac;
|
|
|
|
int possible_overflow = 0;
|
|
|
|
int possibly_clamped = 0;
|
|
|
|
|
|
|
|
uint16_t dac_cmd;
|
|
|
|
|
|
|
|
#define TIMER_RATE 8000 /* how often to read the ADC and update DAC */
|
|
|
|
#define PC_RATE 8000 /* how often to send data to the PC */
|
|
|
|
|
|
|
|
#define DEBUG_ISR_TIME
|
|
|
|
|
|
|
|
#define ADC_WINDOW_MIN 512
|
|
|
|
#define ADC_WINDOW_MIN_STEPTO 1280
|
|
|
|
|
|
|
|
#define ADC_WINDOW_MAX 1536
|
|
|
|
#define ADC_WINDOW_MAX_STEPTO 768
|
|
|
|
|
|
|
|
/* Run mode */
|
|
|
|
void TISR_HANDLER(5)
|
|
|
|
{
|
|
|
|
static int count = 0;
|
|
|
|
static uint16_t dac_cmd;
|
|
|
|
int16_t v;
|
|
|
|
float i;
|
|
|
|
|
|
|
|
/* toggle A9 every time an interrupt occurs */
|
|
|
|
#ifdef DEBUG_ISR_TIME
|
|
|
|
LATAbits.LATA9 = 1;
|
|
|
|
#endif
|
|
|
|
timer_clear_txif(5);
|
|
|
|
|
|
|
|
/* Get most recent sample from 12-bit ADC. */
|
|
|
|
v = adc_get();
|
|
|
|
|
|
|
|
if (v < 0 || v >= 2047)
|
|
|
|
possible_overflow = 1;
|
|
|
|
if (v < ADC_CLAMP_MIN || v >= ADC_CLAMP_MAX)
|
|
|
|
possibly_clamped = 1;
|
|
|
|
|
|
|
|
/* Send data to PC at 1 Hz */
|
|
|
|
/* Send data to PC */
|
|
|
|
if (++count >= (TIMER_RATE / PC_RATE)) {
|
|
|
|
count = 0;
|
|
|
|
|
|
|
@@ -48,44 +58,18 @@ void TISR_HANDLER(5) |
|
|
|
send_data = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert ADC value to current */
|
|
|
|
#pragma xxx
|
|
|
|
#if 0
|
|
|
|
i = adc12_to_current(v);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* Adjust DAC to null this current to 0 */
|
|
|
|
dac_current -= i;
|
|
|
|
#else
|
|
|
|
/* If this current exceeds +-1A, cancel it out at the DAC */
|
|
|
|
if (i < -1.0 || i > 1.0)
|
|
|
|
dac_current -= i;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (dac_current < dac_current_min)
|
|
|
|
dac_current = dac_current_min;
|
|
|
|
if (dac_current > dac_current_max)
|
|
|
|
dac_current = dac_current_max;
|
|
|
|
/* If ADC value is outside the window, step DAC */
|
|
|
|
if (v < ADC_WINDOW_MIN)
|
|
|
|
dac_cmd = adc_to_dac(dac_cmd, v, ADC_WINDOW_MIN_STEPTO, g_scale);
|
|
|
|
else if (v > ADC_WINDOW_MAX)
|
|
|
|
dac_cmd = adc_to_dac(dac_cmd, v, ADC_WINDOW_MAX_STEPTO, g_scale);
|
|
|
|
|
|
|
|
/* Now send it out */
|
|
|
|
dac_cmd = current_to_dac(dac_current);
|
|
|
|
#endif
|
|
|
|
/* Send it out */
|
|
|
|
dac_write(dac_cmd);
|
|
|
|
|
|
|
|
#ifdef DEBUG_ISR_TIME
|
|
|
|
LATAbits.LATA9 = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void send_to_pc(uint16_t adc, uint16_t dac)
|
|
|
|
{
|
|
|
|
/* Sent data format:
|
|
|
|
1Aaa aaaa 0aaa aaDd 0ddd dddd 0ddd dddd
|
|
|
|
Aaaaaaaaaaaa = 12-bit ADC value (2s compliment signed)
|
|
|
|
Dddddddddddddddd = 16-bit DAC command (unsigned)
|
|
|
|
*/
|
|
|
|
uart1_put(0x80 | ((adc & 0x0FE0) >> 5));
|
|
|
|
uart1_put(((adc & 0x001F) << 2) | ((dac & 0xC000) >> 14));
|
|
|
|
uart1_put((dac & 0x3F80) >> 7);
|
|
|
|
uart1_put((dac & 0x007F));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void run_normal(void)
|
|
|
@@ -94,10 +78,8 @@ void run_normal(void) |
|
|
|
led_on();
|
|
|
|
|
|
|
|
/* Assume startup current is 0 */
|
|
|
|
// dac_current = 0.0;
|
|
|
|
// dac_write(current_to_dac(dac_current));
|
|
|
|
// msleep(100);
|
|
|
|
// degauss();
|
|
|
|
msleep(100);
|
|
|
|
dac_cmd = do_calibrate();
|
|
|
|
|
|
|
|
timer_setup_16bit(5, TIMER_RATE, 1);
|
|
|
|
timer_set_priority(5, 6);
|
|
|
@@ -106,20 +88,30 @@ void run_normal(void) |
|
|
|
if (send_data) {
|
|
|
|
/* There's data to send. Disable the ISR briefly
|
|
|
|
while we grab it */
|
|
|
|
uint16_t a, d;
|
|
|
|
uint16_t a, d, o;
|
|
|
|
disable_int({
|
|
|
|
if (possible_overflow) {
|
|
|
|
/* Mark a possible overflow in the output
|
|
|
|
by setting ADC to an unlikely value */
|
|
|
|
possible_overflow = 0;
|
|
|
|
a = 0x0800;
|
|
|
|
} else {
|
|
|
|
if (possibly_clamped) {
|
|
|
|
/* Mark a possible overflow in the output */
|
|
|
|
o = 1;
|
|
|
|
possibly_clamped = 0;
|
|
|
|
}
|
|
|
|
a = send_adc;
|
|
|
|
}
|
|
|
|
d = send_dac;
|
|
|
|
send_data = 0;
|
|
|
|
});
|
|
|
|
send_to_pc(a, d);
|
|
|
|
d = send_dac;
|
|
|
|
send_data = 0;
|
|
|
|
});
|
|
|
|
packet_send_adc_dac(a, d, o);
|
|
|
|
}
|
|
|
|
if (uart1_can_get()) {
|
|
|
|
switch (uart1_get()) {
|
|
|
|
case 'c':
|
|
|
|
disable_int({
|
|
|
|
send_data = 0;
|
|
|
|
dac_cmd = do_calibrate();
|
|
|
|
});
|
|
|
|
packet_send_calibration(g_scale);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|