Wiblocks --- NCO

NCO/NCO.c

00001 
00002 
00003 
00004 #include <NCO.h>
00005 #include <inttypes.h>
00006 #include <avr/interrupt.h>
00007 #include <avr/io.h>
00008 #include "WConstants.h"
00009 
00010 struct nco_struct nco[NCO_NUM_CHS-1];
00011 
00016 void nco_inc(void) {
00017   unsigned char i;
00018   for (i = 0; i < NCO_NUM_CHS; i++) nco_inc_phase_acc(i);
00019 }
00020 
00031 void nco_set_freq(unsigned char ch, double freq) {
00032   nco[ch].inc = (unsigned long)(freq * NCO_NUM_PTS * (unsigned long)(NCO_SCALE / NCO_SAMPLING_RATE));
00033 }
00034 
00042 void nco_init(void) {
00043   unsigned char i;
00044   for (i = 0; i < NCO_NUM_CHS; i++) {
00045     nco[i].acc.acc_long = 0;
00046     nco[i].inc = 0;
00047     switch(i) {
00048     case 0: nco[i].control = NCO_CH0_CONTROL; break;
00049     case 1: nco[i].control = NCO_CH1_CONTROL; break;
00050     case 2: nco[i].control = NCO_CH2_CONTROL; break;
00051     case 3: nco[i].control = NCO_CH3_CONTROL; break;
00052     }
00053   }
00054   PORTB |= (1<<NCO_DAC_LOAD) | (1<<NCO_DAC_LATCH);
00055 }
00056 
00057 
00061 #define nco_dac_toggle_latch { PORTB&=~(1<<NCO_DAC_LATCH); PORTB|=(1<<NCO_DAC_LATCH);}
00062 
00066 #define nco_dac_toggle_load  { PORTB&=~(1<<NCO_DAC_LOAD); PORTB|=(1<<NCO_DAC_LOAD);}
00067 
00068 
00074 void nco_update(void) {
00075   unsigned char i;
00076   unsigned char addr;
00077   cli();
00078   for (i = 0; i < NCO_NUM_CHS; i++) {
00079     nco_inc_phase_acc(i);
00080     SPDR = nco[i].control;
00081     addr = nco_addr(i);
00082     if (nco_round(i)) {
00083       addr += 1;
00084       addr &= NCO_ADDR_MASK;
00085     }
00086     while((SPSR & (1<<SPIF)) == 0);
00087     SPDR = nco_pts[addr];
00088     while((SPSR & (1<<SPIF)) == 0);
00089     nco_dac_toggle_load;
00090     nco_dac_toggle_latch;
00091   }
00092   sei();
00093 }
00094