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; }
void check_current(unsigned char channel) { #ifdef HARDWARE_TRIP if (user_data[channel].i_meas > user_data[channel].i_limit || // "software" check hardware_current_trip(channel)) { // "hardware" check if (trip_time[channel] == 0) trip_time[channel] = time(); /* zero output voltage */ set_hv(channel, 0); u_actual[channel] = 0; user_data[channel].u_dac = 0; /* stop possible ramping */ chn_bits[channel] &= ~DEMAND_CHANGED; chn_bits[channel] &= ~RAMP_UP; chn_bits[channel] &= ~RAMP_DOWN; user_data[channel].status &= ~(STATUS_RAMP_UP | STATUS_RAMP_DOWN); /* raise trip flag */ if ((user_data[channel].status & STATUS_ILIMIT) == 0) { user_data[channel].status |= STATUS_ILIMIT; user_data[channel].trip_cnt++; } } #else if (user_data[channel].i_meas > user_data[channel].i_limit && user_data[channel].u_dac > 40) { unsigned char i; /* ADC could be crashed, so reset it and read current again */ for (i=0 ; i<10 ; i++) { reset_adc(); delay_ms(50); read_hv(channel); if (read_current(channel)) break; } /* now test again for trip */ if (user_data[channel].i_meas > user_data[channel].i_limit) { if (trip_time[channel] == 0) trip_time[channel] = time(); /* ramp down */ chn_bits[channel] &= ~DEMAND_CHANGED; chn_bits[channel] &= ~RAMP_UP; user_data[channel].status &= ~STATUS_RAMP_UP; if (user_data[channel].ramp_down > 0) { /* ramp down if requested */ chn_bits[channel] |= RAMP_DOWN; user_data[channel].status |= STATUS_RAMP_DOWN; } else { /* otherwise go to zero immediately */ set_hv(channel, 0); u_actual[channel] = 0; user_data[channel].u_dac = 0; /* stop possible ramping */ chn_bits[channel] &= ~RAMP_DOWN; user_data[channel].status &= ~STATUS_RAMP_DOWN; } /* raise trip flag */ if ((user_data[channel].status & STATUS_ILIMIT) == 0) { user_data[channel].status |= STATUS_ILIMIT; user_data[channel].trip_cnt++; } } } #endif /* check for trip recovery */ if ((user_data[channel].status & STATUS_ILIMIT) && user_data[channel].trip_cnt < user_data[channel].trip_max && time() >= trip_time[channel] + user_data[channel].trip_time*100) { /* clear trip */ user_data[channel].status &= ~STATUS_ILIMIT; trip_time[channel] = 0; #ifdef HARDWARE_TRIP reset_hardware_trip(); #endif /* force ramp up */ chn_bits[channel] |= DEMAND_CHANGED; } if (user_data[channel].status & STATUS_ILIMIT) led_blink(channel, 3, 100); }
void user_loop(void) { unsigned char xdata channel, i; /* loop over all HV channels */ for (channel=0 ; channel<N_HV_CHN ; channel++) { watchdog_refresh(0); if ((user_data[0].control & CONTROL_IDLE) == 0) { /* set current limit if changed */ if (chn_bits[channel] & CUR_LIMIT_CHANGED) { set_current_limit(user_data[channel].i_limit); chn_bits[channel] &= ~CUR_LIMIT_CHANGED; trip_reset = 1; } /* read back HV and current */ read_hv(channel); read_current(channel); /* check for current trip */ check_current(channel); /* do ramping and regulation */ ramp_hv(channel); regulation(channel); /* set voltage regularly, in case DAC got HV spike */ set_hv(channel, user_data[channel].u_dac); } #ifdef HARDWARE_TRIP if (trip_reset) { reset_hardware_trip(); trip_reset = 0; } #endif /* if crate HV switched off, set DAC to zero */ if (SW1) { for (i = 0 ; i<N_HV_CHN ; i++ ) { user_data[i].u_dac = 0; user_data[i].status |= STATUS_DISABLED; u_actual[i] = 0; set_hv(i, 0); } old_sw1 = 1; } /* if crate HV switched on, indicated changed demand value*/ if (!SW1 && old_sw1) { for (i = 0 ; i<N_HV_CHN ; i++ ) { chn_bits[i] |= DEMAND_CHANGED; user_data[i].status &= ~STATUS_DISABLED; } old_sw1 = 0; } } /* reset ADC once all channels have been read */ reset_adc(); // read_temperature(); }
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; }
char kalibrasi_adc1(int fdy) { unsigned char er; char ada_adc_1; int t; int loop_ulang; int loop; int loop_full_calib; //unsigned char kanal_aktif; unsigned char temp_char; unsigned char cek; unsigned int mask; printf("Start calibrating ADC"); stop_adc(); set_calibrated(0); vTaskDelay(100); reset_adc(); vTaskDelay(100); //cek ID cek = cek_adc_id(); printf(" id = 0x%X \n", cek); vTaskDelay(10); set_iocon(0x00); er = 0; ada_adc_1 = false; for (t=0; t<10; t++) { temp_char = (unsigned char) ((er << 4) + 15); // 0x0F if (er == 8) temp_char = (unsigned char) ((14 << 4) + 15); if (er == 9) temp_char = (unsigned char) ((15 << 4) + 15); loop_ulang = 0; kalib_ulang: loop_ulang++; set_adccon(temp_char); /* kalibrasi zero scale + CHCON */ set_mode(4 + 16); cek = cek_adccon(); //if (cek != temp_char) printf(" !%d ", cek); //serial_puts("tidak cocok"); vTaskDelay(1); loop = 0; printf(" : Kanal %3d : ", (1+t)); while ((cek_mode() & 0x3) != 0x1) { vTaskDelay(10); loop++; if (loop > 50) { if (loop_ulang < 6) { printf(" recalib "); goto kalib_ulang; } printf("\n gagal !\r\n"); ada_adc_1 = false; break; } } if (loop < 50) { printf(" try = %d (OK)\n", loop); ada_adc_1 = true; } /* if (ada_adc_1 == false) { printf("tidak terdapat ADC"); return 1; //break; } */ er++; } if (ada_adc_1 == true) { set_filter((unsigned char) rate_7708); printf(" ADC iocon %d", cek_iocon()); printf("; adccon %d", cek_adccon()); printf("; mode %d\r\n", cek_mode()); set_iocon(0x00); set_calibrated(1); return 1; } else { set_calibrated(0); return 0; } }