/* * Program ID : IRLink-SendPF.nxc * Author : CH, Chen * Build LPF RC Protocol data payload into Hitechnic IRLink sensor I2C buffer * then sending the IR signals */ #define IRLINK_PORT S1 #define I2C_DEVICE 0x02 #define TX_BUFFER_SIZE 0x4D #define TX_MODE 0x4E #define TX_BUFFER_FLAG 0x4F #define MAX_IR_DATA_SIZE 11 //The starting address of I2C register be counted backward payload size(11) from 0x4D, //So, 0x4D - 11 = 0x42 #define TX_BUFFER 0x42 #define MODE_PF 0x02 #define START_SEND 0x01 //Data payload should be encoded to IR transmitting format #define HIGH_BIT_LEN 5 //b 10000 #define LOW_BIT_LEN 3 //b 100 #define START_STOP_BIT_LEN 8 //b 1000 0000 //LPF RC protocol definitions //LPF channel setting #define PF_CH_1 0x00 #define PF_CH_2 0x01 #define PF_CH_3 0x02 #define PF_CH_4 0x03 //LPF Mode setting #define IS_CDM TRUE #define IS_PWM FALSE //LPF output command of Combo Direct Mode #define PF_CDM_FLT 0x00 #define PF_CDM_FWD 0x01 #define PF_CDM_REV 0x02 #define PF_CDM_BRK 0x03 //LPF output command of Combo PWM Mode #define PF_PWM_FLT 0x00 #define PF_PWM_FWD_1 0x01 #define PF_PWM_FWD_2 0x02 #define PF_PWM_FWD_3 0x03 #define PF_PWM_FWD_4 0x04 #define PF_PWM_FWD_5 0x05 #define PF_PWM_FWD_6 0x06 #define PF_PWM_FWD_7 0x07 #define PF_PWM_BRK 0x08 #define PF_PWM_REV_7 0x09 #define PF_PWM_REV_6 0x0A #define PF_PWM_REV_5 0x0B #define PF_PWM_REV_4 0x0C #define PF_PWM_REV_3 0x0D #define PF_PWM_REV_2 0x0E #define PF_PWM_REV_1 0x0F byte data_payload[]; //Build LPF RC Protocol for encoding into IR bit sequence byte I2C_buf[]; //Store IR bit sequence message for transmitting by IRLink /* ******************************************************** * Hex value convert to string * ******************************************************** */ string Hex2String (byte xbyte) { string tr_string=" " , hexcode =" " ; hexcode = SubStr("0123456789ABCDEF" , (xbyte/16), 1); tr_string=StrReplace(tr_string, 0, hexcode); hexcode = SubStr("0123456789ABCDEF" , (xbyte%16), 1); tr_string=StrReplace(tr_string, 1, hexcode); return tr_string; } /* ******************************************************** * Encode LPF RC protocol data payload into IR transmitting * bit sequence format * ******************************************************** */ void EncodeIR() { //0-I2C bus, 1-I2C register, 2~12-Encoding IR data, 13-msg len, 14-mode, 15-trigger ArrayInit(I2C_buf, 0, MAX_IR_DATA_SIZE+5); I2C_buf[0] = I2C_DEVICE; I2C_buf[1] = TX_BUFFER; int I2C_buf_bit_idx; //Current bit index of I2C buffer //Add Start bit b1000 0000 I2C_buf[2] = (1 << (START_STOP_BIT_LEN-1)); I2C_buf_bit_idx = START_STOP_BIT_LEN; //8 (bit7 of byte1) //Encode 2-Byte LPF RC protocol data payload into IR msg for (int xii=0; xii<16; xii++) { I2C_buf[(I2C_buf_bit_idx/8)+2] += (1 << (7-(I2C_buf_bit_idx%8))); I2C_buf_bit_idx += ((data_payload[xii/8] >> (7-(xii%8))) & 0x01)? HIGH_BIT_LEN: LOW_BIT_LEN; //5:3 } //Add Stop bit b1000 0000 I2C_buf[(I2C_buf_bit_idx/8)+2] += (1 << (7-(I2C_buf_bit_idx%8))); //Add I2C buffer data I2C_buf[13] = MAX_IR_DATA_SIZE; //11 I2C_buf[14] = MODE_PF; //0x02 I2C_buf[15] = START_SEND; //0x01 } /* ******************************************************** * Combo Direct Mode data payload: * Nibble 1: 00CC b7~b4 * Nibble 2: 0001 b3~b0 * Nibble 3: BBAA b7~b4 * Nibble 4: lrc b3~b0 0x0F ^ Nibble1 ^ Nibble2 ^ Nibble3 * ******************************************************** */ void Set_PF_ComboDirectMode(const byte x_channel, const byte x_out_a, const byte x_out_b) { byte nibble3 = (x_out_b << 2) + x_out_a; byte lrc = 0x0F ^ x_channel ^ 0x01 ^ nibble3; ArrayInit(data_payload, 0, 2); data_payload[0] = (x_channel << 4) + 0x01; data_payload[1] = (nibble3 << 4) + lrc; EncodeIR(); } /* ******************************************************** * Combo PWM Mode data payload: * Nibble 1: 01CC b7~b4 * Nibble 2: BBBB b3~b0 * Nibble 3: AAAA b7~b4 * Nibble 4: lrc b3~b0 0x0F ^ Nibble1 ^ Nibble2 ^ Nibble3 * ******************************************************** */ void Set_PF_ComboPWMMode(const byte x_channel, const byte x_out_a, const byte x_out_b) { byte nibble1 = x_channel + 0x04; byte lrc = 0x0F ^ nibble1 ^ x_out_b ^ x_out_a; ArrayInit(data_payload, 0, 2); data_payload[0] = (nibble1 << 4) + x_out_b; data_payload[1] = (x_out_a << 4) + lrc; EncodeIR(); } /* ******************************************************** * View LPF RC protocol data payload for encoding * and encoded IR data for transmitting * ******************************************************** */ void ViewIR(string IRCmd) { //string msg1, msg2, msg3, msg4; ClearScreen(); //mmm-Cc-A:aa-B:bb TextOut( 0, LCD_LINE1, "Send by IRLink" ); TextOut( 0, LCD_LINE3, "Mode: " ); TextOut( 0, LCD_LINE4, " CH: " ); TextOut( 0, LCD_LINE5, "OutA: " ); TextOut( 0, LCD_LINE6, "OutB: " ); TextOut(36, LCD_LINE3, SubStr(IRCmd, 0, 3)); //mode:CDM,PWM TextOut(36, LCD_LINE4, SubStr(IRCmd, 5, 1)); //channel:1-4 string _outA = SubStr(IRCmd, 9, 2); //Out A:F1-F7,X,B7-B1,-- if (_outA == "--" ) _outA = "Float" ; else if (_outA == "X " ) _outA = "Brake" ; TextOut(36, LCD_LINE5, _outA); string _outB = SubStr(IRCmd,14, 2); //Out B:F1-F7,X,B7-B1,-- if (_outB == "--" ) _outB = "Float" ; else if (_outB == "X " ) _outB = "Brake" ; TextOut(36, LCD_LINE6, _outB); TextOut( 0, LCD_LINE8, "Sending ... " ); /* TextOut(0, LCD_LINE1, IRCmd); msg1 = Hex2String(data_payload[0]); msg2 = Hex2String(data_payload[1]); TextOut(0, LCD_LINE2, StrCat("PF Cmd: " , msg1,"," ,msg2)); TextOut(0, LCD_LINE3, "Encode:" ); for (int xii=0; xii<3; xii++) { msg1 = Hex2String(I2C_buf[xii*4+2]); msg2 = Hex2String(I2C_buf[xii*4+3]); msg3 = Hex2String(I2C_buf[xii*4+4]); msg4 = Hex2String(I2C_buf[xii*4+5]); TextOut(0, LCD_LINE4-8*xii, StrCat(msg1, "," ,msg2, "," ,msg3, "," ,msg4)); } */ } /* ******************************************************** * I2C write * ******************************************************** */ void SendIR() { int nbytes; while (LowspeedCheckStatus(IRLINK_PORT) == STAT_COMM_PENDING); LowspeedWrite(IRLINK_PORT, 0, I2C_buf); Wait(50); } /* ******************************************************** * Send LPF RC IR signals * ******************************************************** */ void SendPFIR(bool setCDM, const byte out_ch, const byte out_Aport, const byte out_Bport, int xtime) { string cmdString; //mmm-Cc-A:aa-B:bb string xstr1 = NumToStr(out_ch+1), xstr2; if (setCDM) { Set_PF_ComboDirectMode(out_ch, out_Aport, out_Bport); cmdString = "CDM-C" + xstr1; xstr1 = SubStr("--F B X " , out_Aport*2, 2); xstr2 = SubStr("--F B X " , out_Bport*2, 2); } else { Set_PF_ComboPWMMode(out_ch, out_Aport, out_Bport); cmdString = "PWM-C" + xstr1; xstr1 = SubStr("--F1F2F3F4F5F6F7X B7B6B5B4B3B2B1" , out_Aport*2, 2); xstr2 = SubStr("--F1F2F3F4F5F6F7X B7B6B5B4B3B2B1" , out_Bport*2, 2); } cmdString = StrCat(cmdString, "-A:" , xstr1, "-B:" , xstr2); ViewIR(cmdString); unsigned long curr_tick = CurrentTick(); unsigned long tst_tick = curr_tick; while (curr_tick < tst_tick + xtime) { SendIR(); curr_tick = CurrentTick(); } TextOut(0, LCD_LINE8, "Enter to next " ); Wait(500);//until (ButtonPressed(BTNCENTER, TRUE)); } /* ******************************************************** * Initialize I2C sensor * ******************************************************** */ void I2C_Init() { SetInput(IRLINK_PORT, InvalidData, true); SetSensorLowspeed(IRLINK_PORT); while (SensorInvalid(IRLINK_PORT)); } /* ******************************************************** * main routine * ******************************************************** */ task main() { I2C_Init(); ClearScreen(); TextOut(0, LCD_LINE3, "Here is IRLink " ); TextOut(0, LCD_LINE8, "Enter to Go " ); until (ButtonPressed(BTNCENTER, TRUE)); SendPFIR(IS_CDM, PF_CH_1, PF_CDM_FWD, PF_CDM_FWD, 2000); SendPFIR(IS_CDM, PF_CH_2, PF_CDM_FWD, PF_CDM_REV, 2000); SendPFIR(IS_CDM, PF_CH_3, PF_CDM_REV, PF_CDM_REV, 2000); SendPFIR(IS_CDM, PF_CH_4, PF_CDM_BRK, PF_CDM_BRK, 2000); SendPFIR(IS_CDM, PF_CH_4, PF_CDM_FLT, PF_CDM_FLT, 2000); SendPFIR(IS_PWM, PF_CH_1, PF_PWM_FWD_1, PF_PWM_REV_7, 2000); SendPFIR(IS_PWM, PF_CH_2, PF_PWM_FWD_2, PF_PWM_REV_6, 2000); SendPFIR(IS_PWM, PF_CH_3, PF_PWM_FWD_3, PF_PWM_REV_5, 2000); SendPFIR(IS_PWM, PF_CH_4, PF_PWM_FWD_4, PF_PWM_REV_4, 2000); SendPFIR(IS_PWM, PF_CH_1, PF_PWM_FWD_5, PF_PWM_REV_3, 2000); SendPFIR(IS_PWM, PF_CH_2, PF_PWM_FWD_6, PF_PWM_REV_2, 2000); SendPFIR(IS_PWM, PF_CH_3, PF_PWM_FWD_7, PF_PWM_REV_1, 2000); SendPFIR(IS_PWM, PF_CH_4, PF_PWM_FLT, PF_PWM_FLT, 2000); SendPFIR(IS_PWM, PF_CH_4, PF_PWM_BRK, PF_PWM_BRK, 2000); }