X2D lib first commit
X2D.cpp
- Committer:
- sev2000
- Date:
- 2022-10-01
- Revision:
- 25:28895e3d96c5
- Parent:
- 24:eac91efdc315
File content as of revision 25:28895e3d96c5:
#include "mbed.h" #include "rtos.h" #include "X2D.h" #define BUF_SIZE 1000 #define BIT_SIZE 160 //16Bytes + 0xFF + 0x00 + 3 bits + (n * 0 bit inserted by the X2D protocole to cut 0xFF int processData(int size); void write_ctrl_reg(unsigned long write_data); unsigned long read_ctrl_reg(void); DigitalOut Reg_Data(PC_1); // Jaune DigitalOut RxTx(PC_0, 0); // Violet? , reset to force Application mode (not FBL) DigitalOut Tx(PA_9); // Noir DigitalOut UART(PA_0, 1); // Rouge, set to UART mode //DigitalIn CD(PC_0); // Bleu //DigitalIn Rx(PB_7); // Vert //DigitalIn BU(PA_4); // Blanc DigitalIn CLR(PA_1); // Orange DigitalIn RSTO(PC_2); // Gris InterruptIn Rx(PB_7, PullUp); //PlatformMutex sendbit_mutex; pulse_t timeDiff; CircularBuffer<pulse_t, BUF_SIZE> PulseWidth; CircularBuffer<msg_t, 10> MessageTx; CircularBuffer<msg_t, 10> MessageRx; static char cnt_1=0; bool dataBits[BIT_SIZE]={0}; unsigned short maison=0; const unsigned char source = 0x02; const unsigned char trans = 0x02; long startedAt=0; long endedAt=0; Timer xTime; Thread thread(osPriorityAboveNormal); void getPulseF(void) { endedAt = xTime.read_us(); // set timer end for last pin timeDiff.v = endedAt - startedAt; timeDiff.pin = 1; PulseWidth.push(timeDiff); startedAt= endedAt; // set timer start for this pin } void getPulseR(void) { endedAt = xTime.read_us(); // set timer end for last pin timeDiff.v = endedAt - startedAt; timeDiff.pin = 0; PulseWidth.push(timeDiff); startedAt= endedAt; // set timer start for this pin } void wait_posedge(void) { if(CLR != 0) { while(CLR != 0) ; } else ; while(CLR == 0) ; } void wait_negedge(void) { if(CLR == 0) { while(CLR == 0) ; } else ; while(CLR != 0) ; } unsigned long read_ctrl_reg(void) { unsigned long return_value = 0; unsigned long curr_bit = 0 ; int i ; RxTx = 1; //Reg_Data = 0; wait_posedge(); //wait_ms(10); Reg_Data = 1; RxTx = 1; for(i=0;i<=23;i++) { //DBG("i= %d", i); wait_posedge(); curr_bit = Rx ; return_value |= ((curr_bit) << (23-i)) ; } //wait_negedge(); Reg_Data = 0; //clr pin reg_data wait(1) ; return return_value ; } void write_ctrl_reg(unsigned long write_data) { int i ; Reg_Data = 1; //set pin reg_data to Register mode RxTx = 0; //set pin rxtx to Tx mode wait_posedge(); //find posedge for Tcr for(i=0;i<=23;i++) //low code effciency may result in wrong writing { if(((write_data >> (23-i)) & 0x1) == 0) { Tx = 0; } else { Tx = 1; } wait_posedge(); } RxTx = 1; //set pin rxtx to Rx Reg_Data = 0; //set pin reg_data Tx = 0; wait(0.1); } void SendBit(bool value) { // DBG("%d ", value); Tx = !Tx; if(value) { wait_us(800); Tx = !Tx; wait_us(800); } else { wait_us(1600); } } void SendByte(char value) { int i=0; bool bit; //pc.printf("%0.2X ", value); for(i=0; i<8; i++) { bit = (bool)(0x01 & (value>>i)); // LSB first SendBit(bit); if(bit) cnt_1++; else cnt_1=0; if(cnt_1 == 5) { SendBit(0); cnt_1=0; } } } void SendPreamble(void) { int i; //pc.printf("\r\n"); // EM 20210117 remove to avoid glitch (tested) // Tx=1; for(i=0; i<17; i++) SendBit(0); for(i=0; i<6; i++) SendBit(1); SendBit(0); } void SendPostamble(void) { int i; for(i=0; i<8; i++) // Send 0xFF SendBit(1); for(i=0; i<8; i++) SendBit(0); } void SendFrame(unsigned char *data, int length) { int i, chksum=0; RxTx = 0; //set pin rxtx to Tx // EM removed 20210117 don't need since it is already set to 1 at the end // Tx=0; SendPreamble(); cnt_1 =0; // reset counter of consecutive 1 bits for(i=0; i<length; i++) { SendByte(data[i]); chksum += data[i]; } chksum = ~chksum +1; SendByte((char)(chksum>>8)); SendByte((char)chksum); SendPostamble(); RxTx = 1; //set pin rxtx to Rx //EM 20210117 Always finish then restart with Tx=1 (tested) Tx=1; //pc.printf("\r\n"); } void SendAssoc(int zone, int delest) { msg_t msg={0xFF,0xFF,0x02,0xFF,0x02,0xF0,0xFF,0xFF,0xF1,0xE6,0x13,0x03,0x06,0x03, 14}; // zone 4, 3 zone, 6 delest channels, delest chan 3 unsigned char dest = 0; dest = 0x10 + zone-1; msg.data[2] = source; msg.data[4] = trans; msg.data[8] = maison >>8; msg.data[9] = maison & 0xFF; msg.data[10] = dest; msg.data[13] = delest; MessageTx.push(msg); } void SendCmd(int zone, h_mode prog) { //char tab[8]={0xF1,0xE6,0x01,0x10,0x01,0x00,0x03,0x64}; // Zone1 Sun msg_t msg; unsigned char dest = 0; // control 1 char // information 0-8 char int i; dest = 0x10 + zone-1; msg.data[0] = maison >>8; msg.data[1] = maison & 0xFF; msg.data[2] = source; msg.data[3] = dest; msg.data[4] = trans; msg.data[6] = (char)prog; msg.data[7] = 0x64; msg.length = 8; for(i=0; i<3; i++) { msg.data[5]=i; //message count MessageTx.push(msg); //wait_ms(30); } } void SendCmda(char *tab, int length) { msg_t msg; int i; /* dest = 0x10 + zone-1; tab[3] = dest; tab[6] = prog; */ memcpy(msg.data, tab, length); for(i=0; i<3; i++) { msg.data[5] = tab[5] + i; //message count MessageTx.push(msg); //wait_ms(30); } } void TASK_SndRcv(void) { pulse_t pulse; int cnt_1 = 0, rcv_cnt=0; //char tmp[32]={0}; char state=0; char s=0, l=0, bit_ptr=0; msg_t msg; while(true) { rcv_cnt=0; while(!PulseWidth.empty() && rcv_cnt < 200) { PulseWidth.pop(pulse); //sprintf(tmp, "%d, %ld|", pulse.pin, pulse.v); //pc.printf("%s ", tmp); if ((pulse.v > 700) && (pulse.v < 1000)) { // short off detected s++; l=0; } else if ((pulse.v > 1500) && (pulse.v < 1800)) { // long off detected l++; s=0; } else { l=0; s=0; state=0; } switch(state) { case 0: // Detect preamble if(s >= 12) // out of 12 state=1; //pc.printf("%d ", s); break; case 1: // wait start bit (first long) //pc.printf("OK2"); s=0; if (l==1) { state = 2; cnt_1=0; bit_ptr=0; //bit_ptr++; inculde start bit in payload } l=0; break; case 2: //pc.printf(" %d", pulse.v); if (s == 2) { dataBits[bit_ptr] = 1; l=0; s=0; bit_ptr++; cnt_1++; // Count bit for ETX detection } if (l == 1 && s==0) { dataBits[bit_ptr] = 0; l=0; s=0; if(cnt_1 != 5) // skip the 0 after 5 bits = 1 bit_ptr++; cnt_1=0; } if(bit_ptr > BIT_SIZE) { state=0; ERR("Frame too long : dropped\r\n"); } if(cnt_1 == 8) { processData(bit_ptr-1); state=0; //PulseWidth.reset(); } break; } rcv_cnt++; } // Send Frame if (!MessageTx.empty() && rcv_cnt == 0 && RxTx==1) // If message to emit and didn't received message nor sending in progress { MessageTx.pop(msg); // sendbit_mutex.lock(); SendFrame(msg.data, msg.length); // sendbit_mutex.unlock(); } Thread::wait(30); // evey 30 mS we can send a message } } int processData( int size) { int x=0; int i = 0; int j= 0; char nibble[18]={0}; int chksum=0, ETX_pos=0; msg_t message; ETX_pos= size/8; for (i=0; i<ETX_pos; i++) { for (j=0;j<8;j++) { if ( dataBits[x]) nibble[i] |= 1<<j; dataBits[x] =0; // clean variable x++; } } for (i=0; i<ETX_pos-2; i++) // Calculate Checksum { message.data[i] = nibble[i]; message.length = ETX_pos-2; chksum += nibble[i]; } chksum = ~chksum +1; #if __DEBUG__ for (i=0; i<ETX_pos; i++) debug("%0.2X ",nibble[i]); debug("\r\n"); #endif if ( (char)(chksum>>8) != nibble[ETX_pos-2] || (char)chksum != nibble[ETX_pos-1] ) debug("CRC Error\r\n"); else MessageRx.push(message); return 0; } void Init_X2D(void) { unsigned long Ctrl_Reg = 0; Rx.fall(&getPulseF); Rx.rise(&getPulseR); UART = 1; #if NO_STM8 write_ctrl_reg(0x01E22F); // see .xls file ; 1200 baud, deviation =1, Asynchrone, clock OFF Ctrl_Reg = read_ctrl_reg(); DBG("Ctrl_reg = %X", Ctrl_Reg); #endif RxTx = 1; //set pin rxtx to Rx Reg_Data = 0; //set pin reg_data Tx = 0; xTime.start(); xTime.reset(); startedAt = xTime.read_us(); // set initial timer end thread.start(callback(TASK_SndRcv)); }