Ejemplo n.º 1
0
void reset_hardware_trip()
{
   if (!trip_disable) {
      write_adc(REG_IOCONTROL, (1 << 4));            // P1DIR=1,P1DAT=0
      write_adc(REG_IOCONTROL, (1 << 4) | (1 << 0)); // P1DIR=1,P1DAT=1
   }
}
Ejemplo n.º 2
0
unsigned char adc_read(unsigned char channel, float *value)
{
   unsigned long xdata d, start_time;
   unsigned char xdata i;

   /* start conversion */
   channel = adc_index[channel % (N_HV_CHN*2)];
   write_adc(REG_CONTROL, channel << 4 | 0x0F); // adc_chn, +2.56V range
   write_adc(REG_MODE, (1<<4) | (1<<1));        // single conversion, 10 channel mode

   start_time = time();

   while (ADC_NRDY) {
      yield();
      for (i=0 ; i<N_HV_CHN ; i++)
         ramp_hv(i);      // do ramping while reading ADC

      /* abort if no ADC ready after 300ms */
      if (time() - start_time > 30) {
         reset_adc();
         return 0;
      }
   }

   read_adc24(REG_ADCDATA, &d);

   /* convert to volts */
   *value = ((float)d / (1l<<24)) * 2.56;

   /* round result to 6 digits */
   *value = floor(*value*1E6+0.5)/1E6;

   return 1;
}
Ejemplo n.º 3
0
void reset_adc()
{
   ADC_NRES = 0;
   delay_us(OPT_DELAY);
   ADC_NRES = 1;
   delay_us(OPT_DELAY);

   write_adc(REG_FILTER, ADC_SF_VALUE);

#ifndef HARDWARE_TRIP
   /* disable hardware trip FF's */
   write_adc(REG_IOCONTROL, (1 << 4));
#endif
}
Ejemplo n.º 4
0
void adc_read()
{
   unsigned char i;
   unsigned long value;
   float gvalue;

   if (ADC_NRDY)
       return;

   read_adc24(REG_ADCDATA, &value);

   /* convert to volts */
   gvalue = ((float)value / (1l<<24)) * 2.56;

   /* round result to 5 digits */
   gvalue = floor(gvalue*1E5+0.5)/1E5;

   /* apply range */
   if (user_data.adc_25 == 0) {
      if (user_data.uni_adc)
         gvalue *= 10.0/2.56;
      else
         gvalue = gvalue/2.56*20.0 - 10;
   }

   DISABLE_INTERRUPTS;
   user_data.adc[adc_chn] = gvalue;
   ENABLE_INTERRUPTS;

   /* start next conversion */
   adc_chn = (adc_chn + 1) % 8;
   i = adc_index[adc_chn];
   write_adc(REG_CONTROL, i << 4 | 0x0F); // adc_chn, +2.56V range
}
Ejemplo n.º 5
0
void set_current_limit(float value)
{
#ifdef HARDWARE_TRIP
   unsigned short d;

   if (value == 9999) {
      /* disable current trip */
      d = 65535; 
      trip_disable = 1;
      write_adc(REG_IOCONTROL, (1 << 4)); // P1DIR=1,P1DAT=0
   } else {
      
      /* remove reset */
      trip_disable = 0;
      write_adc(REG_IOCONTROL, (1 << 4) | (1 << 0)); // P1DIR=1,P1DAT=1
   
      /* "inverse" calibration */
      value /= user_data[0].cur_gain;
      value += user_data[0].cur_offset;

      /* omit cur_vgain calibration, because statistical mean of
         unbalanced dividers is zero */

      if (value < 0)
         value = 0;

      /* convert current to voltage */
      value = value / DIVIDER * CUR_MULT * RCURR / 1E6;
   
      /* convert to DAC units */
      d = (unsigned short) ((value / 2.5 * 65535) + 0.5);
   }

   /* write current dac */
   write_dac(5, d);

#else // HARDWARE_TRIP

   if (value == 9999)
      trip_disable = 1;
   else
      trip_disable = 0;

#endif // !HARDWARE_TRIP
}
Ejemplo n.º 6
0
unsigned char adc_read(unsigned char channel, float *value)
{
   unsigned long d, start_time;
   unsigned char i;

   /* start conversion */
   channel = adc_index[channel % 8];
   write_adc(REG_CONTROL, channel << 4 | 0x0F); // adc_chn, +2.56V range
   write_adc(REG_MODE, 2);                      // single conversion

   start_time = time();

   while (ADC_NRDY) {
      yield();
      for (i=0 ; i<N_HV_CHN ; i++)
         ramp_hv(i);      // do ramping while reading ADC

      /* abort if no ADC ready after 300ms */
      if (time() - start_time > 30) {

         /* reset ADC */
         ADC_NRES = 0;
         delay_ms(100);
         ADC_NRES = 1;
         delay_ms(300);

         write_adc(REG_FILTER, ADC_SF_VALUE);

         return 0;
      }
   }

   read_adc24(REG_ADCDATA, &d);

   /* convert to volts */
   *value = ((float)d / (1l<<24)) * 2.56;

   /* round result to 6 digits */
   *value = floor(*value*1E6+0.5)/1E6;

   return 1;
}
Ejemplo n.º 7
0
void adc_calib()
{
   unsigned char i;

   for (i=0 ; i<8 ; i++) {

      write_adc(REG_CONTROL, i << 4 | 0x0F);

      /* zero calibration */
      write_adc(REG_MODE, 4);
      while (ADC_NRDY) led_blink(1, 1, 100);

      /* full scale calibration */
      write_adc(REG_MODE, 5);
      while (ADC_NRDY) led_blink(1, 1, 100);
   }

   /* restart continuous conversion */
   write_adc(REG_MODE, 3);
}
Ejemplo n.º 8
0
unsigned char hardware_current_trip(unsigned char channel)
{
unsigned char d;

   /* continuously set FF reset, in case ADC got HV flash */
   if (trip_disable) {
      write_adc(REG_IOCONTROL, (1 << 4)); // P1DIR=1,P1DAT=0
      return 0;
   }

   /* do not check if reset in progres */
   if (trip_reset)
      return 0;

   read_adc8(REG_IOCONTROL, &d);
   
   /* P2 of AD7718 should be low in case of trip */
   if ((d & 2) > 0)
      return 0;

   if (user_data[channel].adc_gain == 1) {
      /* uncalibrated */
      if (user_data[channel].u_meas < 100 && 
          user_data[channel].u_demand > 150)
         return 1;

      return 0; 
   } else {
      /* calibrated */
      if (user_data[channel].u_meas < 5 && user_data[channel].u_demand >= 5)
         return 1;

      return 0;
   }

   return 0;
}
Ejemplo n.º 9
0
void user_init(unsigned char init)
{
   unsigned char i;
   unsigned short address;

   /* all output open drain */
   P1MDOUT = 0x00;
   P2MDOUT = 0x00;

   /* initial nonzero EEPROM values */
   if (init) {
      memset(user_data, 0, sizeof(user_data));
      for (i=0 ; i<N_HV_CHN ; i++) {
         user_data[i].ramp_up    = 300;
         user_data[i].ramp_down  = 300;
         user_data[i].u_limit    = MAX_VOLTAGE;
         user_data[i].i_limit    = MAX_CURRENT;
         user_data[i].ri_limit   = MAX_CURRENT;
         user_data[i].trip_time  = 10;

         user_data[i].adc_gain   = 1;
         user_data[i].dac_gain   = 1;
         user_data[i].cur_gain   = 1;
      }
   }

   /* default control register */
   for (i=0 ; i<N_HV_CHN ; i++) {
      user_data[i].control = CONTROL_REGULATION;
      user_data[i].status = 0;
      user_data[i].u_demand = 0;
      user_data[i].trip_cnt = 0;

      /* check maximum ratings */
      if (user_data[i].u_limit > MAX_VOLTAGE)
         user_data[i].u_limit = MAX_VOLTAGE;

      if (user_data[i].i_limit > MAX_CURRENT && user_data[i].i_limit != 9999)
         user_data[i].i_limit = MAX_CURRENT;

      u_actual[i] = 0;
      t_ramp[i] = time();
   }

   /* jumper and address bits as input */
   JU1 = 1;
   JU2 = 1;
   SW1 = 1;
   SW2 = 1;
   GA_A0 = 1;
   GA_A1 = 1;
   GA_A2 = 1;
   GA_A3 = 1;
   GA_A4 = 1;
   GA_A5 = 1;

   /* read six address bits */
   address = GA_A5;
   address = (address << 1) | GA_A4;
   address = (address << 1) | GA_A3;
   address = (address << 1) | GA_A2;
   address = (address << 1) | GA_A1;
   address = (address << 1) | GA_A0;

   /* each device has 5 channels */
   address *= 5;                   
   
   /* keep high byte of node address */               
   address |= (sys_info.node_addr & 0xFF00);

   sys_info.node_addr = address;

   /* set default group address */
   if (sys_info.group_addr == 0xFFFF)
      sys_info.group_addr = 500;

   /* sample initial state of switch */
   old_sw1 = SW1;
   if (old_sw1)
      for (i=0 ; i<N_HV_CHN ; i++)
         user_data[i].status |= STATUS_DISABLED;

   /* set-up DAC & ADC */
   DAC_CLR  = 1;
   ADC_NRES = 1;
   ADC_NRDY = 1; // input
   ADC_DIN  = 1; // input

   delay_ms(300); // wait for the ADC to come up after power on
   reset_adc();

#ifdef HARDWARE_TRIP
   /* reset current trip FF's */
   reset_hardware_trip();
#else
   /* disable hardware trip FF's */
   write_adc(REG_IOCONTROL, (1 << 4));
#endif

   /* force update */
   for (i=0 ; i<N_HV_CHN ; i++)
      chn_bits[i] = DEMAND_CHANGED | CUR_LIMIT_CHANGED;

   /* LED normally off (inverted) */
   for (i=0 ; i<N_HV_CHN ; i++)
      led_mode(i, 1);

   /* initially, trips are enabled */
   trip_reset = 1;    // reset once
   trip_disable = 0;  // trip initially enabled
   for (i=0 ; i<N_HV_CHN ; i++)
      trip_time[i] = 0;
}
Ejemplo n.º 10
0
void user_init(unsigned char init)
{
   unsigned char i;

   P2MDOUT = 0xF0; // P2.4-7: enable Push/Pull for LEDs
   P3MDOUT = 0;

   /* initial nonzero EEPROM values */
   if (init) {
      memset(user_data, 0, sizeof(user_data));
      for (i=0 ; i<N_HV_CHN ; i++) {
         user_data[i].ramp_up    = 300;
         user_data[i].ramp_down  = 300;
         user_data[i].u_limit    = MAX_VOLTAGE;
         user_data[i].i_limit    = MAX_CURRENT;
         user_data[i].ri_limit   = MAX_CURRENT;
         user_data[i].trip_time  = 10;

         user_data[i].adc_gain   = 1;
         user_data[i].dac_gain   = 1;
         user_data[i].cur_gain   = 1;
      }
   }

   /* default control register */
   for (i=0 ; i<N_HV_CHN ; i++) {
      user_data[i].control = CONTROL_REGULATION;
      user_data[i].status = 0;
      user_data[i].u_demand = 0;
      user_data[i].trip_cnt = 0;

      /* check maximum ratings */
      if (user_data[i].u_limit > MAX_VOLTAGE)
         user_data[i].u_limit = MAX_VOLTAGE;

      if (user_data[i].i_limit > MAX_CURRENT && user_data[i].i_limit != 9999)
         user_data[i].i_limit = MAX_CURRENT;

      u_actual[i] = 0;
      t_ramp[i] = time();
   }

   /* set default group address */
   if (sys_info.group_addr == 0xFFFF)
      sys_info.group_addr = 400;

   /* jumper as input */
   JU0 = 1;
   JU1 = 1;
   JU2 = 1;

   /* read node configuration */
   for (i=0 ; i<N_HV_CHN ; i++) {
      if (JU0 == 0)
         user_data[i].status |= STATUS_NEGATIVE;
      else
         user_data[i].status &= ~STATUS_NEGATIVE;
   
      if (JU1 == 0)
         user_data[i].status |= STATUS_LOWCUR;
      else
         user_data[i].status &= ~STATUS_LOWCUR;
   }

   /* set-up DAC & ADC */
   DAC_CLR  = 1;
   ADC_NRES = 1;
   ADC_NRDY = 1; // input
   ADC_DIN  = 1; // input

   /* reset and wait for start-up of ADC */
   ADC_NRES = 0;
   delay_ms(100);
   ADC_NRES = 1;
   delay_ms(300);

   write_adc(REG_FILTER, ADC_SF_VALUE);

   /* force update */
   for (i=0 ; i<N_HV_CHN ; i++)
      chn_bits[i] = DEMAND_CHANGED | CUR_LIMIT_CHANGED;

   /* LED normally off (inverted) */
   for (i=0 ; i<N_HV_CHN ; i++)
      led_mode(i, 1);

   for (i=0 ; i<N_HV_CHN ; i++)
      trip_time[i] = 0;
}
Ejemplo n.º 11
0
void user_init(unsigned char init)
{
   unsigned char i;
   unsigned short value;

   /* configure crossbar */
   SFRPAGE = CONFIG_PAGE;

   XBR0 = 0x04;  // Enable UART0
   XBR1 = 0x14;  // Enable INT0 and INT1
   XBR2 = 0x40;  // Enable crossbar

   /* enable external interrupts */
   SFRPAGE = TIMER01_PAGE;

   PX0 = 1;      // INT0 high priority
   PX1 = 1;      // INT1 high priority

   IT0 = 1;      // INT0 is edge sensitive
   IT1 = 1;      // INT1 is edge sensitive

   IE0 = 0;      // Clear pending INT0
   IE1 = 0;      // Clear pending INT1

   EX0 = 0;      // INTs will be enabled 
   EX1 = 0;      // later in hv_on()

   SFRPAGE = CONFIG_PAGE;

   P0MDOUT = 0x11;  // P0.0: TX = Push Pull, P0.4: WD
   P1MDOUT = 0x00;  // all open drain
   P2MDOUT = 0x60;  // P2.5/6: HV_POWER
   P3MDOUT = 0x00;

   /* initial nonzero EEPROM values */
   if (init) {
      for (i=0 ; i<N_HV_CHN ; i++) {
         user_data[i].u_demand   = 0;
         user_data[i].trip_cnt   = 0;
         user_data[i].ramp_up    = 100;
         user_data[i].ramp_down  = 100;
         user_data[i].u_limit    = MAX_VOLTAGE;
         user_data[i].i_limit    = MAX_CURRENT;
         user_data[i].ri_limit   = MAX_CURRENT;
         user_data[i].trip_max   = 0;
         user_data[i].trip_time  = 10;

         user_data[i].adc_gain   = 1;
         user_data[i].adc_offset = 0;
         user_data[i].dac_gain   = 1;
         user_data[i].dac_offset = 0;
         user_data[i].cur_vgain  = 0;
         user_data[i].cur_gain   = 1;
         user_data[i].cur_offset = 0;
      }
   }

   /* default control register */
   for (i=0 ; i<N_HV_CHN ; i++) {
      user_data[i].control       = CONTROL_REGULATION;
      user_data[i].status        = 0;
      user_data[i].u_demand      = 0;
      user_data[i].trip_cnt      = 0;

      /* check maximum ratings */
      if (user_data[i].u_limit > MAX_VOLTAGE)
         user_data[i].u_limit = MAX_VOLTAGE;

      if (user_data[i].i_limit > MAX_CURRENT && user_data[i].i_limit != 9999)
         user_data[i].i_limit = MAX_CURRENT;

      if (user_data[i].ri_limit > MAX_CURRENT)
         user_data[i].ri_limit = MAX_CURRENT;

      u_actual[i] = 0;
      t_ramp[i] = time();

      /* read pos/neg jumper */
      JU1 = 1;
      if (JU1 == 0)
         user_data[i].status |= STATUS_NEGATIVE;
      else
         user_data[i].status &= ~STATUS_NEGATIVE;
      user_data[i].status |= STATUS_LOWCUR;
   }

   /* switch off HVs */
   hv_on(0, 0);
   hv_on(1, 0);

   /* HV power reset */
   HV1_POWER = 0;
   HV2_POWER = 0;

   delay_ms(400);

   HV1_POWER = 1;
   HV2_POWER = 1;

   /* set default group address */
   if (sys_info.group_addr == 0xFFFF)
      sys_info.group_addr = 200;

   /* get address from crate backplane read through internal ADC */
   SFRPAGE = LEGACY_PAGE;
   REF0CN  = 0x03;           // use internal voltage reference
   AMX0CF  = 0x00;           // select single ended analog inputs
   ADC0CF  = 0x98;           // ADC Clk 2.5 MHz @ 98 MHz, gain 1
   ADC0CN  = 0x80;           // enable ADC 

   SFRPAGE = ADC0_PAGE;
   sys_info.node_addr = 0;
   for (i=0 ; i<7 ; i++) {
      AMX0SL  = i;           // set multiplexer
      delay_ms(10);          // wait for settling time

      DISABLE_INTERRUPTS;
     
      AD0INT = 0;
      AD0BUSY = 1;
      while (!AD0INT);   // wait until conversion ready
   
      ENABLE_INTERRUPTS;

      value = ADC0L | (ADC0H << 8);
      if (value > 1000)
         sys_info.node_addr |= (1 << i);
   }

   /* each unit contains two addresses */
   sys_info.node_addr <<= 1;

   /* set-up DAC & ADC */
   ADC_NRDY = 1; // input
   ADC_DIN  = 1; // input
   ADC_NRES = 1; // remove reset
   DAC_NCLR = 1; // remove clear

   write_adc(REG_FILTER, ADC_SF_VALUE);

   /* force update */
   for (i=0 ; i<N_HV_CHN ; i++)
      chn_bits[i] = DEMAND_CHANGED | CUR_LIMIT_CHANGED;

   /* LED normally off (inverted) */
   for (i=0 ; i<N_HV_CHN ; i++)
      led_mode(i, 1);

   /* initially, trips are enabled */
   trip_enable(0, 1);
   trip_enable(0, 2);
   trip0 = trip1 = 0;
   trip0_reset = trip1_reset = 0;
   trip_change[0] = trip_change[1] = 0;
   trip_time[0] = trip_time[1] = 0;
}
Ejemplo n.º 12
0
void user_init(unsigned char init)
{
   unsigned char i;

   ADC0CN = 0x00;               // disable ADC 
   DAC0CN = 0x00;               // disable DAC0
   DAC1CN = 0x00;               // disable DAC1
   REF0CN = 0x00;               // disenable internal reference

   /* push-pull:
      P0.0    TX
      P0.1
      P0.2    SW_ADC
      P0.3    DAC_NCS

      P0.4    DAC_SCK
      P0.5    DAC_DIN
      P0.6 
      P0.7    DAC_CLR
    */
   PRT0CF = 0xBD;
   P0 = 0xFF;

   /* push-pull:
      P1.0    SW_DAC
      P1.1
      P1.2    ADC_NRES
      P1.3    ADC_SCLK

      P1.4    ADC_NCS
      P1.5    
      P1.6 
      P1.7    ADC_DIN
    */
   PRT1CF = 0x9D;
   P1 = 0xFF;

   /* initial EEPROM value */
   if (init) {

      for (i = 0; i < 8; i++)
         user_data.dac[i] = 0;
   }

   /* set-up DAC & ADC */
   DAC_CLR = 1;
   ADC_NRES = 1;
   write_adc(REG_FILTER, 82);                   // SF value for 50Hz rejection
   write_adc(REG_MODE, 3);                      // continuous conversion
   write_adc(REG_CONTROL, adc_chn << 4 | 0x0F); // Chn. 1, +2.56V range

   /* write DACs and UNI_BIP */
   for (i=0 ; i<8 ; i++)
      user_write(i+8);

   user_write(16);

   /* swich unipolar/bipolar */
   user_data.uni_dac = 0;
   user_data.uni_adc = 0;
   user_data.adc_25 = 0;
   
   UNI_DAC = user_data.uni_dac;
   UNI_ADC = !user_data.uni_adc;
}