123

Dependencies:   mbed

Fork of LG by igor Apu

DeviceUserProtocolEncoder.c

Committer:
Diletant
Date:
2016-07-03
Revision:
177:672ef279c8e0
Parent:
174:0f86eedd511c

File content as of revision 177:672ef279c8e0:

#include "Device.h"

extern Device device;
extern HashParam hashParamTable[HASH_PARAM_COUNT];
extern HashFunc  hashFuncTable[HASH_FUNC_COUNT];

void InitUserProtocolEncoderDefaultSettings(void) {
}

void InitUserProtocolEncoderState(void) {
  device.user.encoder.error = 0;
  device.user.encoder.count = 0;
  device.user.encoder.CRC = 0;
}

void DeviceStartUserProtocolEncoder(void) {
}

//Next to LineDecode(), PinDecode()
void userEncodeResponse(void) {
  if (device.user.response.enabled) {
    if ((device.user.response.type == RESPONSE_PERIODIC) && (!device.user.response.triggered)) return;

    switch(device.user.response.code){
      case DEV_MODE: EncodeDeviceMode(); break;
      case DELTA_BINS: EncodeDeltaBINS(); break;
      case DELTA_PS: EncodeDeltaPS(); break;
      case DELTA_SF: EncodeDeltaSF(); break;
      case BIT_MODE: EncodeDeviceMode(); break; //Same response as DEV_MODE
      case MAINTENANCE: EncodeMainMode(); break;
      case M0_RATE_1: EncodeMRate(); break;
      case M0_CTL_R: EncodeMCtlR(); break;
      case M0_CTL_A_M: EncodeMCtlAM(); break;
      case M0_CTL_B_M: EncodeMCtlBM(); break;
      case M0_CNT_R: EncodeMCntR(); break;
      case M0_GPH_W: EncodeStart(); EncodeAddress(); Encode8(M0_GPH_W >> 8); Encode8(0); EncodeCRC(); break;
      case H_PARAM8_W:
      case H_PARAM8_R:
      case H_PARAM16_W:
      case H_PARAM16_R:
      case H_PARAM32_W:
      case H_PARAM32_R:
      case H_BYTES_W:
      case H_BYTES_R:
      case FLASH_READ_ALL:
      case FLASH_WRITE_ALL:
        EncodeStart(); EncodeAddress(); Encode16(device.user.response.code); EncodeMessage(); if (device.user.response.message == 0) EncodeParameters(); EncodeCRC();
      break;
      default: EncodeFail();
    }
  }
}

void Encode8(uint8_t param){
  device.user.response.buffer.data[device.user.response.buffer.count] = param;
  device.user.response.buffer.count += 1;
  
  //sprintf(device.service.buffer,"- %2x\r\n", param); WriteConcole(); //Development message
}

void Encode16(uint16_t param) {
  Encode8((param >> 8) & 0xff);
  Encode8(param & 0xff);
}

void EncodeStart(void) {
  device.user.response.ready = 0;        //Disable transmission
  device.user.response.buffer.count = 0; //Clear buffer
  Encode8(0xdd);                         //Write response header code
}

void EncodeEnd(void) {
  device.user.response.enabled = 0;      //Disable response overwrite
  device.user.response.ready = 1;        //Enable transmission
  device.user.response.buffer.position = 0; //Reset transmitter
}

void EncodeFail(void) {
  device.user.response.buffer.count = 0; //Clear buffer
  device.user.response.enabled = 0;      //Disable response overwrite
}

void EncodeAddress(void) {
  Encode8(device.user.address);
}

//TODO: EncodePacket(uint16_t length) - auto reset packet index
void EncodePacket(void) {
  Encode8(device.user.response.packet);
  device.user.response.packet++;
}

void EncodeMessage(void) {
  Encode16(device.user.response.message);
}

void EncodeParameters(void) {
  for (uint8_t i = 0; i < device.user.response.parametersCount; i++){
    uint8_t * b = (uint8_t *)device.user.response.parameters[i].ref;
    for (uint8_t j = 0; j < device.user.response.parameters[i].size; j++){
      Encode8(*b); b++;
    }
  }
}

void EncodeCRC(void) {
  int16_t crc = 0;
  for (int i = 2; i < device.user.response.buffer.count; i++) crc += device.user.response.buffer.data[i];
  Encode16(crc);
  EncodeEnd();
}

void EncodeDeviceMode(void) {
  EncodeStart();
  EncodeAddress();
  EncodeDeviceMode();
  
  uint8_t mode = 0;
  if (device.counters.latch.state.enabled) {
    //External latch mode
    if ((device.counters.latch.state.signal == 0) && (device.counters.latch.state.format == 0))
      //DM_EXT_LATCH_DELTA_PS_LINE
      mode = 3;
    else if ((device.counters.latch.state.signal == 1) && (device.counters.latch.state.format == 0))
      //DM_EXT_LATCH_DELTA_PS_PULSE
      mode = 4;
    else if ((device.counters.latch.state.signal == 0) && (device.counters.latch.state.format == 1))
      //DM_EXT_LATCH_DELTA_BINS_LINE
      mode = 5;
    else if ((device.counters.latch.state.signal == 1) && (device.counters.latch.state.format == 1))
      //DM_EXT_LATCH_DELTA_BINS_PULSE
      mode = 6;
  } else {
    //Internal latch mode
    if (device.counters.rate.state.source == 0) {
      //DM_INT_SIGN_MEANDER_LATCH
      mode = 2;
    } else {
      //DM_INT_10KHZ_LATCH
      mode = 1;
    }
  }
  Encode8(mode);
  
  //Encode SysRgR
  //    Unused 3 bits: => xxxxx000
  //    Hardware: transmitter rate = receiver rate => xxxx1000
  //    Sending response, so transmitter enabled, no case => 1xxx1000
  //    Request received, so receiver enabled, no case => 11xx1000
  switch (device.user.response.rate) {
    case  38400: Encode8(0xc8); break; //11001000
    case 115200: Encode8(0xd8); break; //11011000
    case 460800: Encode8(0xe8); break; //11101000
    case 921600: Encode8(0xf8); break; //11111000
  }
  
  EncodeCRC();
}

void EncodeDeltaPS(void) {
  //TODO: RESPONSE_DELAYED/RESPONSE_PERIODIC
  
  EncodeStart();
  EncodeAddress();
  //Encode angle counts
  Encode16(0);//TODO: PSdiff
  //Prepare parameter
  uint8_t param;
  switch (device.user.response.packet) {
    //High byte of output frequency
    case 0: break;
    //Lo byte of output frequency
    case 1: break;
    //Hi byte of ISACS output
    case 2: break;
    //Lo byte of ISACS output
    case 3: break;
    //Hi byte of dither period
    case 4: break;
    //Lo byte of dither period
    case 5: break;
    //Hi byte of dither pulse width
    case 6: break;
    //Hi byte of dither pulse width
    case 7: break;
    //Hi byte of PLCS output
    case 8: param = ((uint16_t)device.controller.SSP.out[1]) >> 8; break;
    //Lo byte of PLCS output
    case 9: param = (((uint16_t)device.controller.SSP.out[1])) & 0xff; break;
    //Unused 
    case 10: param = 0; break;
    //Unused 
    case 11: param = 0; break;
    //Unused 
    case 12: param = 0; break;
    //Unused 
    case 13: param = 0; break;
    //Hi byte of CCS current[0]
    case 14: param = ((uint16_t)device.ccs.current[0].state.raw) >> 8; break;
    //Lo byte of CCS current[0]
    case 15: param = (((uint16_t)device.ccs.current[0].state.raw)) & 0xff; break;
    //Hi byte of CCS current[1]
    case 16: param = ((uint16_t)device.ccs.current[1].state.raw) >> 8; break;
    //Lo byte of CCS current[1]
    case 17: param = (((uint16_t)device.ccs.current[1].state.raw)) & 0xff; break;
    //Hi byte of TSS gradient
    case 18: param = ((uint16_t)device.tss.gradient.state.raw) >> 8; break;
    //Lo byte of TSS gradient
    case 19: param = (((uint16_t)device.tss.gradient.state.raw)) & 0xff; break;
    //Hi byte of TSS temperature
    case 20: param = ((uint16_t)device.tss.temperature.state.raw) >> 8; break;
    //Lo byte of TSS temperature
    case 21: param = (((uint16_t)device.tss.temperature.state.raw)) & 0xff; break;
  }
  //Encode packet index
  EncodePacket();
  //Reset packet index
  if (device.user.response.packet > 21) device.user.response.packet = 0;
  //Encode parameter
  Encode8(param);
  //Finish encoding
  EncodeCRC();
}

void EncodeDeltaBINS(void) {
  EncodeStart();
  EncodeAddress();
  Encode16(0); Encode16(0); //TODO: BINSDiff_32
  Encode8(0); //Data ok
  EncodeCRC();
}

void EncodeDeltaSF(void) {
//TODO
}

//Deprecated
//Usage: Ask_Gld "Maintenance" button
//Usage: Ask_Gld "x" button
void EncodeMainMode(void) {
  EncodeStart();
  EncodeAddress();
  Encode8(0);      //Version - 0: use extended command to get version
  Encode8(0);      //Serial number - 0: use extended command to get serial number
  EncodeMessage();
  EncodeCRC();
}

void EncodeMCntR(void) {
  EncodeStart();
  EncodeAddress();
  Encode16((int16_t)device.counters.meander.state.a);
  Encode16((int16_t)device.counters.meander.state.b);
  EncodeCRC();
}

void EncodeMRate(void) {
  EncodeStart();
  EncodeAddress();
  //Encode positive meander latched counter data
  Encode16((int16_t)device.counters.meander.state.a);
  //Encode negative meander latched counter data
  Encode16((int16_t)device.counters.meander.state.b);
  //Encode accumulated meander latched counters difference
  uint32_t angle = device.counters.meander.state.angle[0] + device.counters.meander.state.angle[1] >> 1;
  device.counters.meander.state.angle[0] = 0;
  //device.counters.meander.state.angle[1] -= device.counters.meander.state.angle[1] >> 1;//?
  Encode16((int16_t)angle);
  //Encode output frequency
  Encode16((uint16_t)(device.counters.dither.state.amplitude >> 1));
  //Encode ISACS output
  Encode16((uint16_t)device.controller.SSP.out[0]);
  //Encode ISACS error
  Encode16((int16_t)device.isacs.regulator.state.error);
  //Encode dither period
  Encode16((uint16_t)((7680000*16/(device.dither.frequency.state.frequency>>12))));
  //Encode dither phase detector output
  Encode16((int16_t)(device.dither.detector.state.phase));
  //Encode dither pulse width
  Encode16((int16_t)(((7680000 * 2 * device.dither.pulse.state.width >> 8) >> 8) * 8/(device.dither.frequency.state.frequency>>12)));
  //Encode unused
  Encode16(0);
  //Encode PLCS output
  Encode16((uint16_t)device.controller.SSP.out[1]);
  //Encode PLCS error
  Encode16((int16_t)device.plcs.regulator.state.error);
  //Encode unused
  Encode16(0); //T0
  //Encode unused
  Encode16(0); //T1
  //Encode CCS data
  Encode16((int16_t)device.ccs.current[0].state.raw); //T2
  Encode16((int16_t)device.ccs.current[1].state.raw); //T3
  //Encode TSS data
  Encode16((int16_t)device.tss.gradient.state.raw);    //T4
  Encode16((int16_t)device.tss.temperature.state.raw); //T5
  //Encode unused
  Encode16(0);
  //Encode unused
  Encode16(0);
  //Finish encoding
  EncodeCRC();
}

//Deprecated
void EncodeMCtlR(void) {
  EncodeStart();
  EncodeAddress();
  Encode8(device.user.response.code >> 8);
  if (device.user.response.code & 0x10 == 0){
    Encode8(0);      //Encode error status and RgConA attribute (clear register RgConB bit)
    //Prepare RgConA
    uint16_t param = 0;
    if (device.dither.frequency.state.enabled) param |= 1 << 6;
    if (device.dither.amplitude.state.enabled) param |= 1 << 5;
    if (device.sequencer.sampler.state.enabled) param |= 1 << 4;
    if (device.plcs.regulator.state.enabled) param |= 1 << 3;
    if (device.isacs.regulator.state.enabled) param |= 1 << 1;
    Encode16(param); //Encode RgConA
  } else {
    Encode8(0x10);   //Encode error status and RgConB attribute (set register RgConB bit)
    Encode16(device.counters.rate.state.source); //Encode RgConB
  }
  //Finish encoding
  EncodeCRC();
}

//Deprecated
void EncodeMCtlAM(void) {
  EncodeStart();
  EncodeAddress();
  Encode8(device.user.response.code >> 8);
  //TODO:
  Encode8(0x10); Encode8(0);Encode8(0); //Encode RgConA content
  //Finish encoding
  EncodeCRC();
}

//Usage: Ask_Gld "Maintenance" button
void EncodeMCtlBM(void) {
  EncodeStart();
  EncodeAddress();
  Encode8(device.user.response.code >> 8);
  //TODO:
  Encode8(0); Encode8(0);Encode8(0); //Encode RgConB content
  //Finish encoding
  EncodeCRC();
}

void EncodeMParamR(void) {
  EncodeStart();
  EncodeAddress();
  EncodeMessage();
  EncodeCRC();
}

void EncodeMParamW(void) {
  EncodeStart();
  EncodeAddress();
  EncodeMessage();
  EncodeCRC();
}