File content as of revision 12:ce8ae07fd23b:
#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(info_t *message, int size);
DigitalOut Reg_Data(PC_1);
DigitalOut RxTx(PB_0);
DigitalOut Tx(PA_9);
DigitalOut UART(PA_0, 1);
DigitalIn CD(PC_0);
//DigitalIn Rx(PB_7);
DigitalIn BU(PA_4);
DigitalIn CLR(PA_1);
DigitalIn RSTO(PC_2);
InterruptIn Rx(PB_7, PullUp);
pulse_t timeDiff;
CircularBuffer<pulse_t, BUF_SIZE> PulseWidth;
bool dataBits[BIT_SIZE]={0};
long startedAt=0;
long endedAt=0;
Timer xTime;
Thread thread;
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;
static char cnt=0;
pc.printf("%0.2X ", value);
for(i=0; i<8; i++)
{
bit = (bool)(0x01 & (value>>i)); // LSB first
SendBit(bit);
if(bit)
cnt++;
else
cnt=0;
if(cnt == 5)
{
SendBit(0);
cnt=0;
}
}
}
void SendPreamble(void)
{
int i;
//pc.printf("\r\n");
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(char *data, int length)
{
int i, chksum=0;
RxTx = 0; //set pin rxtx to Tx
Tx=0;
// wait_us(500);
//wait_ms(1);
SendPreamble();
for(i=0; i<length; i++)
{
SendByte(data[i]);
chksum += data[i];
}
chksum = ~chksum +1;
SendByte((char)(chksum>>8));
SendByte((char)chksum);
SendPostamble();
// Tx=1;
RxTx = 1; //set pin rxtx to Rx
pc.printf("\r\n");
}
void SendCmd(int zone, h_mode prog)
{
char tab[8]={0xF1,0xE6,0x01,0x10,0x01,0x00,0x03,0x64}; // Zone1 Sun
char maison[2]={0xF1,0xE6};
char source = 0x02;
char dest = 0;
char trans = 0x02;
// control 1 char
// information 0-8 char
int i;
dest = 0x10 + zone-1;
tab[2] = source;
tab[3] = dest;
tab[4] = trans;
tab[6] = (char)prog;
for(i=0; i<3; i++)
{
tab[5]=i; //message count
SendFrame(tab, 8);
wait_ms(30);
}
}
void SendCmda(char *tab, int lenght)
{
char buf[16];
int i;
/* dest = 0x10 + zone-1;
tab[3] = dest;
tab[6] = prog;
*/
memcpy(buf, tab, lenght);
for(i=0; i<3; i++)
{
buf[5] = tab[5] + i; //message count
SendFrame(buf, lenght);
wait_ms(30);
}
}
void TASK_RcvMessages(info_t *message)
{
pulse_t pulse;
int cnt_1 = 0, i=0;
char tmp[32]={0};
char state=0;
char s=0, l=0, bit_ptr=0;
while(true)
{
i=0;
while(!PulseWidth.empty() && i<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)
bit_ptr++;
cnt_1=0;
}
if(bit_ptr > BIT_SIZE)
{
state=0;
pc.printf("Frame too long : dropped\r\n");
}
if(cnt_1 == 8)
{
processData(message, bit_ptr-1);
state=0;
//PulseWidth.reset();
}
break;
}
i++;
}
Thread::wait(100);
}
}
int processData(info_t *message, int size)
{
int x=0;
int i = 0;
int j= 0;
char nibble[18]={0}, cnt=0;
int chksum=0, ETX_pos=0;
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
chksum += nibble[i];
chksum = ~chksum +1;
#ifdef __DEBUG__
for (i=0; i<ETX_pos; i++)
pc.printf("%0.2X ",nibble[i]);
if ( (char)(chksum>>8) != nibble[ETX_pos-2] || (char)chksum != nibble[ETX_pos-1] )
pc.printf(" CRC Error");
pc.printf("\r\n");
#endif
if((nibble[5]&0xF0) == 0 && nibble[2]==1 && nibble[4]!=nibble[2])
{
message->zone=nibble[3]-0x10 +1;
message->mode=(h_mode)nibble[6];
}
return 0;
}
void Init_X2D(info_t *message)
{
unsigned long Ctrl_Reg = 0;
Rx.fall(&getPulseF);
Rx.rise(&getPulseR);
UART = 1;
write_ctrl_reg(0x01E22F); // 1200 baud, deviation =1, Asynchrone
Ctrl_Reg = read_ctrl_reg();
DBG("Ctrl_reg = %X", Ctrl_Reg);
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_RcvMessages, message));
}