You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

552 lines
17 KiB

#define _ISR_C
#include <xc.h>
#include <GenericTypeDefs.h>
#include <peripheral/i2c.h>
#include <peripheral/adc10.h>
#include "mcu.h"
#include "isr.h"
#include "pars.h"
#include "main.h"
#include "iron.h"
#include "PID.h"
#include "io.h"
volatile unsigned int ISRComplete = 0;
volatile int I2CCommands;
volatile int I2CCCommand;
void ISRInit(){
int i;
ISRStep = 0;
ADCStep = 0;
ISRTicks = 1;
PHEATER = 0;
I2CStep = 0;
I2CCommands = 0;
I2CCCommand = 0;
I2CIdle = 1;
ISRStopped = 0;
EEPAddrR = 0xFFFF;
EEPDataR = 0;
EEPCntR = 0;
EEPAddrW = 0xFFFF;
EEPDataW = 0;
EEPCntW = 0;
for(i = 2; i--;){
PIDVars[i].NoHeater = 255;
PIDVars[i].NoSensor = 255;
PIDVars[i].ShortCircuit = 255;
PIDVars[i].HInitData = 1;
PIDVars[i].OffDelay = 1600;
}
OffDelayOff = 1600;
VIBuffCnt = 0;
mainFlags.Calibration = 0;
ISRComplete = 0;
mainFlags.PowerLost = 0;
}
void ISRStop(){
ISRStopped = 1;
while(!(ISRStopped & 2));
while(!I2CIdle);
mcuADCStop();
mcuStopISRTimer();
mcuCompDisable();
mainFlags.PowerLost = 0;
}
void ISRStart(){
mcuDisableInterrupts();
mcuCompDisable();
mcuADCStop();
mcuStopISRTimer();
if(mainFlags.ACPower){
while(MAINS);
while(!MAINS);
_delay_us(1000);
}
mcuDCTimerReset();
mcuCompEnableH2L();
VIBuffCnt = 0;
ISRStopped = 0;
mainFlags.PowerLost = 0;
mcuEnableInterrupts();
}
void I2CAddCommands(int c)
{
int i;
i=mcuDisableInterrupts();
I2CCommands |= c;
if(I2CIdle)mcuI2CWakeUp();
mcuRestoreInterrupts(i);
}
void OnPowerLost(){
if(!mainFlags.PowerLost){
mainFlags.PowerLost = 1;
HEATER = 0;
mcuADCStop();
mcuStopISRTimer();
mcuCompDisable();
ISRStep = 0;
ADCStep = 0;
}
}
void ISRHigh(int src){
static int OldHeater;
t_PIDVars *PV;
t_IronConfig *IC;
UINT32 dw;
switch(src){
case CompH2L:
if(!mainFlags.ACPower) OnPowerLost();
case DCTimer:
if(ISRStep != 9)ISRComplete = 0;
ISRStep = 0;
break;
case CompL2H:
return;
}
PV = (t_PIDVars *)&PIDVars[1];
IC = (t_IronConfig *)&IronPars.Config[1];
if((ADCStep < 2) || (IC->Type == 0)){
PV = (t_PIDVars *)&PIDVars[0];
IC = (t_IronConfig *)&IronPars.Config[0];
}
switch (ISRStep){
case 0:
OldHeater = HEATER;
if(ISRStopped){
HEATER = 0;
if(!(ISRStopped & 2)){
ISRStopped |= 2;
mcuADCStop();
VIBuffCnt = 0;
}
}
else{
mcuCompDisable();
if(mainFlags.PowerLost) return;
dw = OffDelayOff;
if(HEATER && dw < PV->OffDelay) dw = PV->OffDelay;
dw >>= 4;
dw -= ((OffDelayOff >> 4) * 115) >> 8;
if(dw > 1000) dw = 1000;
mcuStartISRTimer_us(dw); //delay to zero current when AC power
}
break;
case 1:
//if(OldHeater && (ADCStep & 1))LATBbits.LATB7= ! LATBbits.LATB7;
if(ADCStep & 1){
HEATER = 0;
}else{
if(ISRComplete) mcuCompEnableL2H();
}
if(mainFlags.ACPower){
mcuStartISRTimer_us(50);
}
else{
mcuStartISRTimer_us(450);
}
break;
case 2:
//if(OldHeater && (ADCStep & 1))LATBbits.LATB7= ! LATBbits.LATB7;
mcuStartISRTimer_us(150);
mcuADCStartManual();
mcuADCRefVref();
CHSEL1 = IC->InputP;
CHSEL2 = IC->InputN;
CHPOL = IC->InputInv;
if(ISRComplete){
if((dw = VIBuffCnt >> 2) && (VBuff[dw] < 90) && (IBuff[dw] < 16)){ //power lost if <0.5A and <7.4V
OnPowerLost();
ISRStep = 0;
return;
}
if(ADCStep & 1){
if(mainFlags.ACPower && CompLowTime){ //calculate delay from comparator trigger to zero current (just before zero cross)
dw = (OldHeater ? PV->OffDelay : OffDelayOff);
if(dw <= 1600)dw = CompLowTime << 4;
dw -= dw >> 4;
dw += CompLowTime;
if(dw < 1600)dw = 1600;
if(OldHeater){
PV->OffDelay = dw;
}
else{
OffDelayOff = dw;
}
}
else{
OffDelayOff = PV->OffDelay = 1600;
}
CompLowTime = 0;
}
else{
if(OldHeater){
UINT32 i, l;
if((i = l = VIBuffCnt) > 1){
UINT32 cv, ci, sv = 0, si = 0, sp = 0, ri = 0, rv = 0, r = 0;
for(i--, l--; i--;){
cv = (VBuff[i] + VBuff[i + 1]);
ci = IBuff[i];
if(ci < 1023 && ri < ci && VBuff[i] < 1023 && VBuff[i + 1] < 1023){
ri = ci;
rv = cv;
r = 0;
}
if(ci >= 1023){
if(!r && ri) r = ((rv * 6738) / ri) >> 9;
if(r) ci = ((cv * 6738) / r) >> 9;
}
sv += cv * cv;
si += ci * ci;
sp += ci * cv;
if(BuffEmpty){
Buff1[i] = ci;
Buff2[i] = cv;
}
}
Buff1[l + 1] = 256;
BuffEmpty = 0;
r = (ri ? (((rv * 6738) / ri) + 256) >> 9 : 0x7FFF);
//if(ri)r = ((rv * 6738) / ri) >> 8;
// 6738 = 10 * 256 * (((Rs1 * (R48 / R42)) / VRef) * 1024) / (((R51 / (R47 + R51)) / VRef) * 1024)
// = 10 * 256 * (((0.003 * (47K / 1.5K)) / 3.0V) *1024) / (((1K / (27K + 1K)) / 3.0V) * 1024)
// = 6737.92
sv = (sv + (l >> 1)) / l;
si = (si + (l >> 1)) / l;
l *= (UINT32)(391 * 2);
sp = (sp + (l >> 1)) / l;
// 391 = (((R51 / (R47 + R51)) / VRef) * 1024) * (((Rs1 * (R48 / R42)) / VRef) * 1024)
// = (((1K / (27K + 1K)) / 3.0V) * 1024) * (((0.003 * (47K / 1.5K)) /3.0V) * 1024)
// = 391,13549206349206349206349206349
dw = 1024;
if(IronPars.Config[1].Type) dw >>= 1;
PV->HV = (mcuSqrt(sv * dw) + 32) >> 6;
PV->HI = (mcuSqrt(si * dw) + 16) >> 5;
PV->HP = ((sp * dw) + 512) >> 10;
PV->HR = r;
PV->HNewData = 1;
}
}
}
}
VIBuffCnt = 0;
ISRComplete = 0;
break;
case 3:
mcuADCRead(ADCH_RT,1);
break;
case 4:
if(ADCStep == 0){
ADCData.VRT = mcuADCRES;
}
else{
ADCData.VRT += mcuADCRES;
}
//if(OldHeater && (ADCStep & 1))LATBbits.LATB7= ! LATBbits.LATB7;
mcuADCRead(ADCH_TEMP, 4);
break;
case 5:
//if(OldHeater && (ADCStep & 1))LATBbits.LATB7= ! LATBbits.LATB7;
if(!mainFlags.Calibration){
CHSEL1 = 0;
CHSEL2 = 0;
}
ADCData.HeaterOn = PHEATER;
ADCData.VTEMP[ADCStep & 1] = mcuADCRES >> 2;
if(ADCStep & 1) {
if(PV->HR > 3000) {
if(PV->NoHeater < 255) PV->NoHeater++;
}
else{
PV->NoHeater = 0;
}
if(PV->HR < 8){
if(PV->ShortCircuit < 255) PV->ShortCircuit++;
}
else{
PV->ShortCircuit = 0;
}
if(ADCData.VTEMP[1] >= 1023){
if(PV->NoSensor < 255) PV->NoSensor++;
}
else{
PV->NoSensor = 0;
}
PID(ADCStep >> 1);
if(PV->KeepOff)PV->KeepOff--;
}
ADCStep = (ADCStep + 1) & 3;
PV = (t_PIDVars *)&PIDVars[1];
IC = (t_IronConfig *)&IronPars.Config[1];
if((ADCStep < 2) || (IC->Type == 0)){
PV = (t_PIDVars *)&PIDVars[0];
IC = (t_IronConfig *)&IronPars.Config[0];
}
HCH = IC->HChannel;
CBANDA = IC->CBandA;
CBANDB = IC->CBandB;
I2CData.CurrentA.ui16 = IC->CurrentA;
I2CData.CurrentB.ui16 = IC->CurrentB;
I2CData.Gain.ui16 = IC->Gain;
I2CData.Offset.ui16 = IC->Offset;
if(!mainFlags.PowerLost)I2CAddCommands(I2C_SET_CPOT | I2C_SET_GAINPOT | I2C_SET_OFFSET);
if(!(ADCStep & 1)){
PV->PWM += PV->PIDDuty;
PHEATER = ((PV->PWM>>24)!=0);
PV->PWM &= 0x00FFFFFF;
}
if(mainFlags.PowerLost || PV->KeepOff || mainFlags.Calibration || IC->Type == 0 || IC->Type == 255 )PHEATER = 0;
HEATER = PHEATER;
mcuADCStartAuto();
mcuStartISRTimer(C_PER);
break;
case 6:
mcuStartISRTimer(C_PER);
break;
case 7:
mcuStartISRTimer(C_PER);
if(!MAINS || ((VBuff[dw = (mcuIBuffPos() >> 2) - 1] < 90) && (IBuff[dw] < 16))){ //power lost if <0.5A and <7.4V
OnPowerLost();
return;
}
mcuCompEnableH2L();
break;
case 8:
ISRTicks++;
ISRComplete = 1;
break;
}
if(ISRStep<255)ISRStep++;
}
void I2CISRTasks(){
int i;
UINT16 ui;
BOOL CmdOK;
if(I2CCCommand){
I2CStep++;
}
else{
I2CStep=0;
i=mcuDisableInterrupts();
if(I2CCommands &= 0xFF){
I2CCCommand = 1;
while(I2CCCommand &= 0xFF){
if(I2CCommands & I2CCCommand){
I2CCommands -= I2CCCommand;
I2CIdle=0;
break;
}
I2CCCommand <<= 1;
}
}
else{
I2CIdle=1;
}
mcuRestoreInterrupts(i);
}
CmdOK = TRUE;
switch(I2CCCommand){
case I2C_SET_CPOT:
switch(I2CStep){
case 0:
mcuI2CStart();
break;
case 1:
mcuI2CSendAddrW(CPOT);
break;
case 2:
mcuI2CSendByte(0x40); //write to TCON, disable general ca??
break;
case 3:
ui=0xFF;
if(I2CData.CurrentA.ui16 == 0) ui &= 0xF0; //disconnect R0A when currentA is 0
if(I2CData.CurrentA.ui16 >= 256) ui &= 0xFE; //disconnect R0B when currentA is MAX
if(I2CData.CurrentB.ui16 == 0) ui &= 0x0F; //disconnect R1A when currentB is 0
if(I2CData.CurrentB.ui16 >= 256) ui &=0xEF; //disconnect R1B when currentB is MAX
mcuI2CSendByte(ui); //write to TCON
break;
case 4:
mcuI2CSendByte(I2CData.CurrentA.ui16 >> 8); //Wiper0
break;
case 5:
mcuI2CSendByte(I2CData.CurrentA.ui16 & 0xFF);
break;
case 6:
mcuI2CSendByte((I2CData.CurrentB.ui16 >> 8) | 0x10); //Wiper1
break;
case 7:
mcuI2CSendByte(I2CData.CurrentB.ui16 & 0xFF);
break;
case 8:
I2CCCommand=0;
mcuI2CStop();
break;
}
break;
case I2C_SET_GAINPOT:
switch(I2CStep){
case 0:
mcuI2CStart();
break;
case 1:
mcuI2CSendAddrW(GAINPOT);
break;
case 2:
mcuI2CSendByte(I2CData.Gain.ui16 >> 8);
break;
case 3:
mcuI2CSendByte(I2CData.Gain.ui16 & 0xFF);
break;
case 4:
I2CCCommand=0;
mcuI2CStop();
break;
}
break;
case I2C_SET_OFFSET:
switch(I2CStep){
case 0:
mcuI2CStart();
break;
case 1:
mcuI2CSendAddrW(OFFADC);
break;
case 2:
mcuI2CSendByte(0b01011000);
break;
case 3:
mcuI2CSendByte(I2CData.Offset.ui16 >> 2);
break;
case 4:
mcuI2CSendByte((I2CData.Offset.ui16 << 6) & 0xFF);
break;
case 5:
I2CCCommand=0;
mcuI2CStop();
break;
}
break;
case I2C_EEPWRITE:
switch(I2CStep){
case 0:
mcuI2CStart();
break;
case 1:
mcuI2CSendAddrW(EEP);
break;
case 2:
if(CmdOK = mcuI2CIsACK())mcuI2CSendByte(EEPAddrW >> 8);
break;
case 3:
mcuI2CSendByte(EEPAddrW & 0xFF);
break;
case 4:
mcuI2CSendByte(*((UINT8*)EEPDataW));
break;
case 5:
EEPCntW--;
if(EEPCntW){
EEPDataW++;
EEPAddrW++;
if(((EEPAddrW & 31) == 0) || (I2CCommands & (I2CCCommand-1))){ //Abort if EEPROM page boundary is crossed, or if there is pending higher priority command
CmdOK = FALSE;
}
else {
I2CStep = 4;
mcuI2CSendByte(*((UINT8*)EEPDataW));
}
}
else{
EEPAddrW=0xFFFF;
I2CCCommand=0;
mcuI2CStop();
}
break;
}
break;
case I2C_EEPREAD:
switch(I2CStep){
case 0:
mcuI2CStart();
break;
case 1:
mcuI2CSendAddrW(EEP);
break;
case 2:
if(CmdOK = mcuI2CIsACK())mcuI2CSendByte(EEPAddrR >> 8);
break;
case 3:
mcuI2CSendByte(EEPAddrR & 0xFF);
break;
case 4:
mcuI2CStart();
break;
case 5:
mcuI2CSendAddrR(EEP);
break;
case 6:
mcuI2CReceiverEnable();
break;
case 7:
*((UINT8 *)EEPDataR) = mcuI2CGetByte();
EEPCntR--;
if(EEPCntR){
EEPDataR++;
EEPAddrR++;
if(((EEPAddrR & 31) == 0) || (I2CCommands & (I2CCCommand - 1))){ //Abort if EEPROM page boundary is crossed, or if there is pending higher priority command
mcuI2CReceiverDisable();
CmdOK = FALSE;
}
else{
mcuI2CACK();
I2CStep = 5;
}
}
else{
mcuI2CReceiverDisable();
EEPAddrR = 0xFFFF;
I2CCCommand=0;
mcuI2CStop();
}
break;
}
break;
default:
I2CCCommand=0;
break;
}
if(CmdOK == FALSE){
I2CCommands |= I2CCCommand;
I2CCCommand=0;
mcuI2CStop();
}
}
#undef _ISR_C