143 lines
2.8 KiB
C
143 lines
2.8 KiB
C
#include "config.h"
|
|
#include "adc.h"
|
|
#include "adcext.h"
|
|
#include "dac.h"
|
|
#include "uart.h"
|
|
#include "timer.h"
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include "calibrate.h"
|
|
#include "util.h"
|
|
#include "mode.h"
|
|
#include "led.h"
|
|
#include "packet.h"
|
|
|
|
int send_data = 0;
|
|
uint16_t send_adc;
|
|
uint16_t send_dac;
|
|
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;
|
|
int16_t v;
|
|
|
|
#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 < ADC_CLAMP_MIN || v >= ADC_CLAMP_MAX)
|
|
possibly_clamped = 1;
|
|
|
|
/* Send data to PC */
|
|
if (++count >= (TIMER_RATE / PC_RATE)) {
|
|
count = 0;
|
|
|
|
/* Send most recent sample and old DAC value */
|
|
send_adc = v;
|
|
send_dac = dac_cmd;
|
|
send_data = 1;
|
|
}
|
|
|
|
#define WINDOW
|
|
#ifdef WINDOW
|
|
/* 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);
|
|
#else
|
|
dac_cmd = adc_to_dac(dac_cmd, v, 1024, g_scale);
|
|
#endif
|
|
|
|
/* Send it out */
|
|
dac_write(dac_cmd);
|
|
|
|
#ifdef DEBUG_ISR_TIME
|
|
LATAbits.LATA9 = 0;
|
|
#endif
|
|
}
|
|
|
|
void run_normal(void)
|
|
{
|
|
int i;
|
|
uart1_init(500000);
|
|
|
|
led_pattern(0b00110011);
|
|
|
|
/* Keep writing zero to the DAC for about 30 seconds after startup,
|
|
or until we receive a character on the UART */
|
|
while(uart1_can_get())
|
|
uart1_get();
|
|
for (i = 0; i < 1500; i++) {
|
|
dac_write(DAC_MID);
|
|
if (uart1_can_get()) {
|
|
uart1_get();
|
|
break;
|
|
}
|
|
msleep(10);
|
|
}
|
|
|
|
led_on();
|
|
|
|
/* Assume startup current is 0 */
|
|
msleep(100);
|
|
dac_cmd = do_calibrate();
|
|
|
|
timer_setup_16bit(5, TIMER_RATE, 1);
|
|
timer_set_priority(5, 6);
|
|
|
|
while(1) {
|
|
if (send_data) {
|
|
/* There's data to send. Disable the ISR briefly
|
|
while we grab it */
|
|
uint16_t a, d, o;
|
|
disable_int({
|
|
if (possibly_clamped) {
|
|
/* Mark a possible
|
|
* overflow in the
|
|
* output */
|
|
o = 1;
|
|
possibly_clamped = 0;
|
|
} else o = 0;
|
|
a = send_adc;
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|