#include "config.h"
#include <xc.h>
#include "io.h"
#include "oled.h"
#include "font.h"
#include "portbits.h"
#include "sspslave.h"

volatile unsigned char inByte=0;
volatile unsigned char tx=0;
int acc=0;
char d[6];
volatile char flag=0;       //set if IRQ needs something to happen
char i;
int dispVal=0;          //for display value
char dMode=0;           //for OLED display
char swFlag=0;          //when a switch state needs to be sent

void setTX(void);       //wrapper for encoding tx data

void main(void) {
    ioinit();
    I2Cinit();
    OLEDinit();    
    OLEDflip(OLED_CONNECTOR_AT_TOP);
    sspSlaveInit();
    reInit();
    buttonInit();
    GIE=1;
    col=37;
    page=2;
    largeFontChar(CHAR_MINUS,arial,dMode);
    largeFontChar(CHAR_MINUS,arial,dMode);
    largeFontChar(CHAR_MINUS,arial,dMode);
    while(flag==0){} //wait until valid comms
    OLEDclear();
    while(1){
        col=0;
        page=1;
        if(inByte){ //normal
            dispVal=((int)(inByte)-128)*5;
            dMode=OLED_NORMAL;
        }else{
            dMode=OLED_HALFTONE;
        }
        getDigits((unsigned int)abs(dispVal),d);
        if(dispVal<0){      //negative value
            if(d[2]=='0'){
                largeFontChar(CHAR_SPACE,arial,dMode);
                largeFontChar(CHAR_MINUS,arial,dMode);
            }else{
                largeFontChar(CHAR_MINUS,arial,dMode);
                largeFontChar(d[2],arial,dMode);                
            }
        }else{      //zero/positive
            if(d[2]=='0'){
                largeFontChar(CHAR_SPACE,arial,dMode);
                largeFontChar(CHAR_SPACE,arial,dMode);
            }else{
                largeFontChar(CHAR_SPACE,arial,dMode);
                largeFontChar(d[2],arial,dMode);                            
            }
        }
        largeFontChar(d[3],arial,dMode);
        largeFontChar(CHAR_POINT,arial,dMode);
        largeFontChar(d[4],arial,dMode);
        largeFontChar(CHAR_d,arial,dMode);
        largeFontChar(CHAR_B,arial,dMode);        
        page=6;
        if(inByte){
            col=14;
            largeFontCharArray(" MUTE OFF ",arialSmall,OLED_HALFTONE);                    
        }else{
            col=19;
            largeFontCharArray(" MUTE ON ",arialSmall,OLED_NORMAL);                               
        }
        acc=acc+getRE();
        if(buttonDown()){swFlag=1;}   
        setTX();
        for(i=0;i<30;i++){
            if(flag){flag=0;break;}
            __delay_ms(10);
        }
    }
    return;
}

void setTX(void){
    int t=0;
    char intcon=INTCON; //get state
    GIE=0;             //interrupts off
    if(tx==0){          //free for us to change
        if(swFlag){
            tx=SW_FLAG_VALUE;
            swFlag=0;
        }else{
            t=abs(acc)/SW_DIVIDER;
            if(t){
                if(t>SW_LIMIT){t=SW_LIMIT;}
                if(acc>=0){
                    acc=acc-(t*SW_DIVIDER);
                    tx=128+(char)t;
                }else{
                    acc=acc+(t*SW_DIVIDER);
                    tx=128-(char)t;
                }
            }
        }
    }
    INTCON=intcon;      //restore interrupts    
}

void __interrupt () isr (void) {
    if(PIR1bits.SSP1IF && PIE1bits.SSP1IE){
        PIR1bits.SSP1IF=0;
        inByte=SSP1BUF;
        SSP1BUF=tx;
        tx=0;       //flag as empty
        flag=1;
    }
    if(IOCIF && IOCIE){
        iocxfbits.RE_A=0;   //clear flags
        iocxfbits.RE_B=0;    
        //reState=reState|portbits.RE_A*8|portbits.RE_B*4; //then capture state, we shouldn't miss anything
        if(portbits.RE_A){reState=reState|8;}   //this is better
        if(portbits.RE_B){reState=reState|4;}
        reState=reState&0xF;
        reAccum=reAccum+reRes[reState];
        reState=reState>>2;
    }
    if(IOCIF && IOCIE){
        iocxfbits.SW1=0;   //clear flags
        if(portbits.SW1){buttonState=buttonState|2;}   //this is better
        buttonState=buttonState&3;
        if(buttonState==1){buttonPress=1;}      //changing from high to low == press
        buttonState=buttonState>>1;
    }
}

