Version:0.9 StartHTML:0000000105 EndHTML:0000119412 StartFragment:0000001499 EndFragment:0000119396 mikroIDE

//control variables
unsigned int POT_delay_time;
unsigned int POT_mod_speed;
unsigned int POT_mod_depth;


bit BOOL_can_record;
signed char SENS_ring_sens;
sbit PIN_ring_sens at RF0_bit;
sbit PIN_hold_button at RE0_bit;
sbit PIN_range_1 at RE1_bit;
sbit PIN_range_2 at RE2_bit;
sbit PIN_range_3 at RE3_bit;
sbit PIN_range_4 at RE4_bit;


//sampling variables
unsigned int adc_sample;
signed int adc_value;
signed int dac_value;
//signed int current_sample;
signed long int audio_sample_long;
signed int audio_sample;

char MEM_WE=6;
unsigned long MEM_address;
unsigned long MEM_address_dac;
unsigned long MEM_address_range;

//modulation
unsigned char sine_table[256] = {128,131,134,137,140,143,146,149,152,156,159,162,165,168,171,174,176,179,182,185,188,191,193,196,199,201,204,206,209,211,213,216,218,220,222,224,226,228,230,232,234,236,237,239,240,242,243,245,246,247,248,249,250,251,252,252,253,254,254,255,255,255,255,255,255,255,255,255,255,255,254,254,253,252,252,251,250,249,248,247,246,245,243,242,240,239,237,236,234,232,230,228,226,224,222,220,218,216,213,211,209,206,204,201,199,196,193,191,188,185,182,179,176,174,171,168,165,162,159,156,152,149,146,143,140,137,134,131,128,124,121,118,115,112,109,106,103,99,96,93,90,87,84,81,79,76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,19,18,16,15,13,12,10,9,8,7,6,5,4,3,3,2,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,2,3,3,4,5,6,7,8,9,10,12,13,15,16,18,19,21,23,25,27,29,31,33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,79,81,84,87,90,93,96,99,103,106,109,112,115,118,121,124};
unsigned char sine_table_count;
unsigned int sine_table_int;
unsigned long int sine_table_long;
unsigned int modulation=0;


//output pins
sbit Chip_Select_DAC at LATD10_bit;
sbit Chip_Select_ADC at LATD11_bit;
sbit RAM1_CS at LATD4_bit;


//misc
char buffer;
sbit LED at LATG9_bit;
//signed int temp_headroom_high;
char ADC_turn=0;
unsigned int temp_count=0;
unsigned long temp_long;
//unsigned long temp_long_count=0;



//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################


//sample audio from external ADC
void ADC_Input() {
     DisableInterrupts();
     
     Chip_Select_ADC = 1;
     //delay_us(1);
     Chip_Select_ADC = 0;
     
     //adc_value = SPI2_Read(buffer);             //old SPI read
     delay_us(2);
     adc_sample = SPI4BUF;      //actual read
     SPI4BUF = adc_sample;      //refresh
     //delay_us(4);
     //IFS2.B6 = 0;

     //Chip_Select_ADC = 1;
     //adc_value = adc_value << 3;
     //adc_value = adc_value - 32768;
     

     
     adc_sample.F15 = 0;
     adc_sample.F14 = 0;
     adc_sample.F13 = 0;
     
     //if (adc_sample > 4090) {LED = 1;}
     
     adc_value = adc_sample - 4090;     //0 bias
     

     
     /*
     if (adc_value > temp_headroom_high) {
         temp_headroom_high = adc_value;
     }
     */

     EnableInterrupts();
}

//output audio to external DAC
void DAC_Output(unsigned int valueDAC) {
     DisableInterrupts();
     //valueDAC = valueDAC + 32768;
     //valueDAC.F15 =~ valueDAC.F15;
     Chip_Select_DAC = 0;
     SPI3_Write(valueDAC);
     Chip_Select_DAC = 1;
     EnableInterrupts();
}

//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################

//write to mem
//262,144 possible samples
void MEM_Write(unsigned long MEM_address, signed int MEM_sample) {
     unsigned int MEM_cmd_add_1, MEM_cmd_add_2;
     
     MEM_address <<= 1;                        //double address for int sample length
     MEM_cmd_add_1 = MEM_address >> 16;    //isolate address lsb
     MEM_cmd_add_1.F8 = 0;                  //sequential write command
     MEM_cmd_add_1.F9 = 1;
     MEM_cmd_add_2 = MEM_address;           //address middle and msb
     
     DisableInterrupts();
     RAM1_CS = 0;
     SPI3_Write(MEM_cmd_add_1);
     SPI3_Write(MEM_cmd_add_2);
     SPI3_Write(MEM_sample);
     RAM1_CS = 1;
     EnableInterrupts();
}

//read mem
unsigned int MEM_Read(unsigned long MEM_address) {
     unsigned int MEM_cmd_add_1, MEM_cmd_add_2;
     signed int MEM_value;
     
     MEM_address <<= 1;                        //double address for int sample length
     MEM_cmd_add_1 = MEM_address >> 16;    //isolate address lsb
     MEM_cmd_add_1.F8 = 1;                  //sequential read command
     MEM_cmd_add_1.F9 = 1;
     MEM_cmd_add_2 = MEM_address;           //address middle and msb

     DisableInterrupts();
     RAM1_CS = 0;
     SPI3_Write(MEM_cmd_add_1);
     SPI3_Write(MEM_cmd_add_2);
     MEM_value = SPI3_Read(buffer);
     MEM_value <<= 1;
     RAM1_CS = 1;
     EnableInterrupts();
     
     return MEM_value;
}

//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################

//initialize on-chip ADC
void InitADC(unsigned char ADC_channel) {
  static unsigned int WhichBit = 1;
  DisableInterrupts();
  WhichBit = (WhichBit << ADC_channel);
  TRISB |= WhichBit;
  AD1PCFG = ~WhichBit;
  AD1CON1bits.SSRC = 7;
  AD1CON1bits.FORM = 0;
  AD1CON1bits.ASAM = 0;
  AD1CHS = 0;
  AD1CHSbits.CH0SA = ADC_channel;
  AD1CSSL = 0;
  AD1CON3bits.ADRC = 0;
  AD1CON3bits.SAMC = 0x03;
  AD1CON3bits.ADCS = 0x02;
  AD1CON2 = 0;
  AD1CON1bits.ON = 1;
  EnableInterrupts();
 }

//sample on-chip ADC
unsigned int GetADC(void) {
  DisableInterrupts();
  AD1CON1bits.SAMP = 1;
  while(!AD1CON1bits.DONE);
  return(ADC1BUF0);
  EnableInterrupts();
 }
 
 
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################


void UART3_Write_Line(signed long *uart_text) {
     char t[12];
     DisableInterrupts();
     LongToStr(uart_text, t);
     UART3_Write_Text(t);
     UART3_Write(13);
     UART3_Write(10);
     EnableInterrupts();
}


//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################

void Sampling_loop() iv IVT_TIMER_1 ilevel 7 ics ICS_SRS {
     DisableInterrupts();
     T1IF_bit = 0;             // reset timer

     //direction/confusion control
     if (PIN_ring_sens == 1) {
        SENS_ring_sens = 1;
     } else {
        SENS_ring_sens = -1;
     }

     
     //bidirectional address counter       (maybe remove -1/=1 for ADC counter)
    if (SENS_ring_sens == 1) {                                    //if sens is forward
        if (MEM_address >= MEM_address_range) {
            MEM_address = 0;
        } else {
            MEM_address = MEM_address + SENS_ring_sens;
        }
        MEM_address_dac = MEM_address + SENS_ring_sens;
        if (MEM_address_dac > MEM_address_range) {
            MEM_address_dac = 0;
        }
    } else {                                                      //if sens is backward
        if (MEM_address == 1) {
            MEM_address = MEM_address_range;
            LED = 1;
            LED = 0;
        } else {
            MEM_address = MEM_address + SENS_ring_sens;
        }
        MEM_address_dac = MEM_address + SENS_ring_sens;
        if (MEM_address_dac == 0) {
            MEM_address_dac = MEM_address_range;
        }
    }

     //sampling / temp hold mode
     if (PIN_hold_button == 0) {
        ADC_Input();
        MEM_Write(MEM_address, adc_value);
     }


     //playback
     dac_value = MEM_Read(MEM_address_dac);
     DAC_Output(dac_value);



     EnableInterrupts();
}

//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################

//low speed timer
void UI_Functions() iv IVT_TIMER_2 ilevel 7 ics ICS_SRS {
     DisableInterrupts();
     T2IF_bit = 0;             // reset timer
    
    //LED = 0;  //clipping thing
     //UART3_Write_Line(adc_value);
     
//ridiculous ADC turn thing to compensate for ADC slowness
if (ADC_turn == 0) {
   InitADC(5);
} else if (ADC_turn == 1) {
   InitADC(4);
} else if (ADC_turn == 2) {
   InitADC(3);
}



if (ADC_turn == 2) {                          //AN3
   /*
   POT_delay_time = GetADC(void);
   POT_delay_time = POT_delay_time << 2;      //*4
   POT_delay_time = POT_delay_time + 1110;
   */

   temp_long = GetADC(void);
   temp_long = temp_long * 326;
   temp_long = temp_long / 100;
   POT_delay_time = temp_long + 1110;
   PR1 = POT_delay_time + modulation;

} else if (ADC_turn == 0) {                  //AN5
   POT_mod_depth = GetADC(void);
   POT_mod_depth = POT_mod_depth >> 2;

} else if (ADC_turn == 1) {                  //AN4
   POT_mod_speed = GetADC(void);
   //if (POT_mod_speed == 0) {
      //POT_mod_speed = 1;
   //}
   PR3 = POT_mod_speed << 8;
   if (PR3 < 1024) {
      PR3 = 1024;
   }
   //UART3_Write_Line(PR3);
}


 
//ADC turn thing continued
if (ADC_turn == 2) {
     ADC_turn = 0;
   } else {
     ADC_turn++;
}



//range switching
if (PIN_range_1 == 1) {
    MEM_address_range = 3924;
} else if (PIN_range_2 == 1) {
    MEM_address_range = 15750;
} else if (PIN_range_3 == 1) {
    MEM_address_range = 63000;
} else if (PIN_range_4 == 1) {
    MEM_address_range = 252000;
}

   /*
   if (temp_count == 200) {
      UART3_Write_Line(temp_headroom_high);
      temp_headroom_high = 0;
      
      temp_count = 0;
   } else {
      temp_count++;
   }
    */
    
     EnableInterrupts();
}



//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################

//modulation
void Timer3Interrupt() iv IVT_TIMER_3 ilevel 7 ics ICS_SRS {
  T3IF_bit = 0;
    sine_table_long = sine_table[sine_table_count];
    sine_table_count = sine_table_count + 1;
    
    sine_table_long = sine_table_long * POT_mod_depth;
    sine_table_long = sine_table_long / 256;
    modulation = sine_table_long;
    

}

//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################


void main() {
  UART3_Init(57600);
  SPI4_Init_Advanced(_SPI_MASTER, _SPI_16_BIT, 32, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE);
  SPI3_Init_Advanced(_SPI_MASTER, _SPI_16_BIT, 2, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE);

  DDPCONbits.JTAGEN = 0;
  
  //analog pins
  AD1PCFG = 0xFFD7;   //11011111 11010111;
  TRISB3_bit = 1;     //pot ADC as input
  TRISB5_bit = 1;     //pot ADC as input
  
  TRISD10_bit = 0; //DAC CS as output
  TRISD11_bit = 0; //ADC CS as output
  
  TRISG9_bit = 0;    //LED
  TRISD4_bit = 0;  //RAM CS as output
  TRISG6_bit = 0;

  //TRISE0_bit = 1;    //fuck you
  //PIN_ring_sens = 1;
  
  Chip_Select_DAC = 1;
  Chip_Select_ADC = 1;
  RAM1_CS = 1;
  
  LED = 0;

  PIN_ring_sens = 1;
  PIN_hold_button = 1;

//sampling timer
ON__T1CON_bit = 0;        // disable Timer1
  TMR1 = 0;                 // reset timer value to zero
  //PR1 = 1110;              // 13.9us 72khz
  PR1 = 4440;
  T1IP0_bit = 1;            // set interrupt
  T1IP1_bit = 1;            // priority
  T1IP2_bit = 1;            // to 7
  TCKPS0_bit = 0;           // Set Timer Input Clock
  TCKPS1_bit = 0;           // Prescale value to 1:1
  T1IE_bit = 1;             // Enable Timer1 Interrupt
  ON__T1CON_bit = 1;        // Enable Timer1

//low speed timer
ON__T2CON_bit = 0;        // disable Timer2
  TMR2 = 0;                 // reset timer value to zero
  PR2 = 640;              // Load period register
  T2IP0_bit = 1;            // set interrupt
  T2IP1_bit = 1;            // priority
  T2IP2_bit = 1;            // to 7
  TCKPS0_T2CON_bit = 1;           // Set Timer Input Clock
  TCKPS1_T2CON_bit = 1;           // Prescale value to 1:256
  TCKPS2_bit = 1;
  T2IE_bit = 1;             // Enable Timer2 Interrupt
  ON__T2CON_bit = 1;        // Enable Timer2

  

//modulation timer
  //ON__T3CON_bit = 0;
  T3CON         = 0x8050;
  T3IE_bit         = 1;
  T3IF_bit         = 0;
  T3IP0_bit         = 1;
  T3IP1_bit         = 1;
  T3IP2_bit         = 1;
  PR3                 = 62500;   //62500
  TMR3                 = 0;
  //ON__T3CON_bit = 1;
  
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################

//defaults and setup

delay_ms(10);
EnableInterrupts();       // Enable all interrupts

//RAM write-enable
RAM1_CS = 0;
SPI3_Write(MEM_WE << 8);
RAM1_CS = 1;

//control variables
POT_delay_time = 1024;
POT_mod_speed = 1024;
POT_mod_depth = 1024;



MEM_address_range = 252000;
MEM_address = 0;
//MEM_address_offset = 0;

BOOL_can_record = 1;          //rec enabled
SENS_ring_sens = 1;           //forward

//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################
//####################################################################################################################################################################


   while (1) {

        //LED = ~LED;

          //UART2_Write_Line(current_sample);


        /*
        if (current_sample == 14020) {
          LED = 1;
        } else {
          LED = 0;
        }
        */
        
        //delay_ms(250);
        //LED = ~LED;
  }

   
  }