Browse Source

Start refactoring timer stuff for internal ADC

git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@5928 ddd99763-3ecb-0310-9145-efcb8ce7c51f
tags/zoom-1.0
jim 16 years ago
parent
commit
136fb77276
7 changed files with 154 additions and 63 deletions
  1. +9
    -9
      firmware/adcext.c
  2. +5
    -5
      firmware/adcext.h
  3. +1
    -0
      firmware/config.h
  4. +82
    -0
      firmware/timer.c
  5. +31
    -0
      firmware/timer.h
  6. +22
    -45
      firmware/zoom.c
  7. +4
    -4
      firmware/zoom.mcp

firmware/adc.c → firmware/adcext.c View File

@@ -1,5 +1,5 @@
#include "config.h"
#include "adc.h"
#include "adcext.h"
/* The ADC (AD7846) is tricky, as new conversions start
automatically when the previous data read finishes.
@@ -28,7 +28,7 @@
#define wait_25ns() nop()
/* Initialize ADC */
void adc_init(void)
void adcext_init(void)
{
int i;
@@ -42,13 +42,13 @@ void adc_init(void)
/* Trigger a dummy read so we're prepared for the
next conversion */
(void) adc_read();
(void) adcext_read();
}
/* Start a conversion if it hasn't already been started.
Wait for conversion to finish.
Read the result and return the raw 32-bit value. */
uint32_t adc_read(void)
uint32_t adcext_read(void)
{
uint32_t val;
int i;
@@ -91,7 +91,7 @@ uint32_t adc_read(void)
The return value is full int32 range but only the high
24 should be significant: low 3 will always be 0,
and the next 5 will be sub-resolution (see datasheet). */
int32_t adc_convert(uint32_t raw)
int32_t adcext_convert(uint32_t raw)
{
int sigmsb = (raw >> 28) & 3;
@@ -107,12 +107,12 @@ int32_t adc_convert(uint32_t raw)
/* Start a new conversion. If a conversion was already started
but the result was not read, this does nothing. */
void adc_start_conversion(void)
void adcext_start_conversion(void)
{
/* If we had a previous conversion ready to read,
read it out so we can start a new conversion instead */
if (adc_is_conversion_ready())
(void) adc_read();
if (adcext_is_conversion_ready())
(void) adcext_read();
/* Start conversion by completing previous read */
LAT_SCK = 0;
@@ -123,7 +123,7 @@ void adc_start_conversion(void)
}
/* Return 1 if a conversion is finished and ready to be read, 0 otherwise */
int adc_is_conversion_ready(void)
int adcext_is_conversion_ready(void)
{
if (LAT_SCK == 0 && R_SDO == 0)
return 1;

firmware/adc.h → firmware/adcext.h View File

@@ -2,22 +2,22 @@
#define ADC_H
/* Initialize ADC */
void adc_init(void);
void adcext_init(void);
/* Start a conversion if it hasn't already been started.
Wait for conversion to finish.
Read the result and return the raw 32-bit value. */
uint32_t adc_read(void);
uint32_t adcext_read(void);
/* Convert a raw 32-bit value into a signed result.
The return value range is -(2^31) to (2^31)-1 */
int32_t adc_convert(uint32_t raw);
int32_t adcext_convert(uint32_t raw);
/* Start a new conversion. If a conversion was already started
but the result was not read, this does nothing. */
void adc_start_conversion(void);
void adcext_start_conversion(void);
/* Return 1 if a conversion is in progress, 0 otherwise */
int adc_is_conversion_ready(void);
int adcext_is_conversion_ready(void);
#endif

+ 1
- 0
firmware/config.h View File

@@ -13,6 +13,7 @@ typedef signed long long int64_t;
typedef unsigned long long uint64_t;

#define FCY 40000000
#define TMR1_RATE 8000

void config_init(void);



+ 82
- 0
firmware/timer.c View File

@@ -0,0 +1,82 @@
#include "config.h"
#include "timer.h"
/* Setup a 16-bit timer to overflow at the specified frequency
timer = 1-9
freq = Hz, or 0 to disable the timer.
interrupt = 1 to enable interrupt, 0 to disable
*/
int timer_setup_16bit(int timer, uint32_t freq, int ie)
{
uint32_t period;
uint16_t prescale;
if (timer < 1 || timer > 9)
return -1;
if (freq == 0) {
switch(timer) {
case 1: T1CONbits.TON = 0; return 0;
case 2: T2CONbits.TON = 0; return 0;
case 3: T3CONbits.TON = 0; return 0;
case 4: T4CONbits.TON = 0; return 0;
case 5: T5CONbits.TON = 0; return 0;
case 6: T6CONbits.TON = 0; return 0;
case 7: T7CONbits.TON = 0; return 0;
case 8: T8CONbits.TON = 0; return 0;
case 9: T9CONbits.TON = 0; return 0;
}
}
/* Figure out timer prescaler and period values. Max period
is 65535 (PRx = 65534) so we can still attain 100% duty
cycle when using a timer for PWM. */
if ((period = FCY / (freq * 1L)) <= 65535)
prescale = 0;
else if ((period = FCY / (freq * 8L)) <= 65535)
prescale = 1;
else if ((period = FCY / (freq * 64L)) <= 65535)
prescale = 2;
else if ((period = FCY / (freq * 256L)) <= 65535)
prescale = 3;
else
prescale = 3, period = 65535;
if (period > 0)
period -= 1;
switch (timer) {
#define __timer_setup_case(x) \
case x: \
T##x##CONbits.TON = 0; \
T##x##CONbits.TCKPS = prescale; \
PR##x = period; \
T##x##CONbits.TON = 1; \
break
__timer_setup_case(1);
__timer_setup_case(2);
__timer_setup_case(3);
__timer_setup_case(4);
__timer_setup_case(5);
__timer_setup_case(6);
__timer_setup_case(7);
__timer_setup_case(8);
__timer_setup_case(9);
#undef __timer_setup_case
}
/* Enable interrupt if requested */
timer_clear_txif(timer);
switch (timer) {
case 1: IEC0bits.T1IE = ie; break;
case 2: IEC0bits.T2IE = ie; break;
case 3: IEC0bits.T3IE = ie; break;
case 4: IEC1bits.T4IE = ie; break;
case 5: IEC1bits.T5IE = ie; break;
case 6: IEC2bits.T6IE = ie; break;
case 7: IEC3bits.T7IE = ie; break;
case 8: IEC3bits.T8IE = ie; break;
case 9: IEC3bits.T9IE = ie; break;
}
return 0;
}

+ 31
- 0
firmware/timer.h View File

@@ -0,0 +1,31 @@
#ifndef TIMER_H
#define TIMER_H
#include "config.h"
/* Setup a 16-bit timer to overflow at the specified frequency
timer = 1-9
freq = Hz, or 0 to disable the timer.
ie = 1 to enable interrupt, 0 to disable
*/
int timer_setup_16bit(int timer, uint32_t freq, int ie);
#define TISR_HANDLER(x) \
__attribute__((__interrupt__,auto_psv)) _T##x##Interrupt(void)
/* Clear TxIF corresponding to a timer */
#define timer_clear_txif(timer) do { \
if ((timer) == 1) IFS0bits.T1IF = 0; \
if ((timer) == 2) IFS0bits.T2IF = 0; \
if ((timer) == 3) IFS0bits.T3IF = 0; \
if ((timer) == 4) IFS1bits.T4IF = 0; \
if ((timer) == 5) IFS1bits.T5IF = 0; \
if ((timer) == 6) IFS2bits.T6IF = 0; \
if ((timer) == 7) IFS3bits.T7IF = 0; \
if ((timer) == 8) IFS3bits.T8IF = 0; \
if ((timer) == 9) IFS3bits.T9IF = 0; \
} while(0)
#endif

+ 22
- 45
firmware/zoom.c View File

@@ -6,58 +6,35 @@
#include <stdio.h>
#include <math.h>

#define TEST_LEN 128

uint32_t samples[TEST_LEN];
uint32_t mean;
uint32_t stdev;

/* Read TEST_LEN samples and compute mean & stdev. */
void test_adc(void)
int32_t tmr1_ms = 0;
void TISR_HANDLER(1)
{
uint32_t tmp = 0;
int i;

for (i = 0; i < TEST_LEN; i++) {
samples[i] = adc_read();
tmp += samples[i];
}

mean = tmp / TEST_LEN;

tmp = 0;
for (i = 0; i < TEST_LEN; i++)
tmp += (samples[i] - mean) * (samples[i] - mean);
stdev = sqrt(tmp);
}

int main(void)
{
int32_t i;
int32_t j;
config_init();
uart1_init(115200);
tmr1_init();
tmr1_wait_ms(100);

adc_init();
uart1_init(1000000);
adcext_init();
dac_init();
uart1_put_string("ADC/DAC test\r\n");

top:
for (i = 0; i < 32768; i ++) {
dac_write(i);
tmr1_wait_ms(1);
for (j = 0; j < TEST_LEN; j++) {
uart1_put_dec(i);
uart1_put(' ');
uart1_put_dec(adc_convert(adc_read()));
uart1_put_string("\r\n");
}
timer_setup_16bit(1, 1000, 1);

TRISDbits.TRISD0 = 0;
TRISDbits.TRISD1 = 1;
TRISDbits.TRISD2 = 1;

while(1) {
/* these are ints, so it should be atomic */
/*
tmp = output_count;
tmp2 = dacval;
uart1_put_hex((tmp & 0x7F) | (LATDbits.LATD0 ? 0x80 : 0x00));
uart1_put_hex((tmp2 & 0xFF00) >> 8);
uart1_put_hex((tmp2 & 0x00FF));
uart1_put('\r');
*/
}

uart1_put_string("-----\r\n");
goto top;
return 0;
for(;;) continue;
}

+ 4
- 4
firmware/zoom.mcp View File

@@ -37,14 +37,14 @@ file_001=config.c
file_002=uart.c
file_003=util.c
file_004=dac.c
file_005=adc.c
file_006=timer.c
file_005=timer.c
file_006=adcext.c
file_007=config.h
file_008=uart.h
file_009=util.h
file_010=dac.h
file_011=adc.h
file_012=timer.h
file_011=timer.h
file_012=adcext.h
file_013=p33fj256gp710.gld
[SUITE_INFO]
suite_guid={479DDE59-4D56-455E-855E-FFF59A3DB57E}


Loading…
Cancel
Save