File content as of revision 17:2a9e02dccd88:
#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);
DigitalOut Reg_Data(PC_1); // Jaune
DigitalOut RxTx(PC_0); // Bleu
DigitalOut Tx(PA_9); // Noir
DigitalOut UART(PA_0, 1); // Rouge
//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;
bool dataBits[BIT_SIZE]={0};
const unsigned char maison[2]={0xF1,0xE6};
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;
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(unsigned 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 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[0];
msg.data[9] = maison[1];
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[0];
msg.data[1] = maison[1];
msg.data[2] = source;
msg.data[3] = dest;
msg.data[4] = trans;
msg.data[6] = (char)prog;
msg.data[7] = 0x64;
for(i=0; i<3; i++)
{
msg.data[5]=i; //message count
msg.lenght = 8;
MessageTx.push(msg);
//wait_ms(30);
}
}
void SendCmda(char *tab, int lenght)
{
msg_t msg;
int i;
/* dest = 0x10 + zone-1;
tab[3] = dest;
tab[6] = prog;
*/
memcpy(msg.data, tab, lenght);
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;
pc.printf("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 emmit and didn't received message nor sending in progress
{
MessageTx.pop(msg);
// sendbit_mutex.lock();
SendFrame(msg.data, msg.lenght);
// 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.lenght = ETX_pos-2;
chksum += nibble[i];
}
chksum = ~chksum +1;
#ifdef __DEBUG__
for (i=0; i<ETX_pos; i++)
pc.printf("%0.2X ",nibble[i]);
pc.printf("\r\n");
#endif
if ( (char)(chksum>>8) != nibble[ETX_pos-2] || (char)chksum != nibble[ETX_pos-1] )
pc.printf("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;
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_SndRcv));
}