HobbyKing.com New Products Flash Sale
Reply
Thread Tools
Old Dec 17, 2012, 08:17 AM
Registered User
Joined May 2011
655 Posts
Quote:
Originally Posted by RW9UAO View Post
at now development stopped. i lost interest and motivation.

But why? I'm really sad to hear that!
Please go on! We all appreciate your work very much!

I took a look at that forum, but the Google translate made it impossible to understand, and my russian is a bit rusty...

Could you summarize it for us?
I think there will be a lot of questions if we start to understand the contents...

For example there is the question of DSMX loosing signal, and your two method to find the connection again, i.e. simply wait on a channel (which could take long time) or start to scan in reverse order of the channel hopping sequence, but in the latter case there is a chance, that the tx and the rx simply owerjump each other...

And I have a lot of questions about the telemetry communication too:
If I understand well, if there is telemetry capable tx and rx, then at binding they will be bound too as a separate tx and rx, but it is not clear for me will it happen on the same two channels (since telemetry data will be sent between the normal packages), or will it choose another two for it. Furthermore it is valid only for the DSM2, I guess. How does it happen in case of DSMX?
FDR_ is offline Find More Posts by FDR_
Reply With Quote
Sign up now
to remove ads between posts
Old Dec 17, 2012, 04:20 PM
Registered User
Joined Oct 2012
268 Posts
What do you need to translate? If RW9UAO is willing to write up a summary, I can translate. The problem with Russian forum is that it probably has all the info but in a series of not well connected messages, which is hard to decipher even if your Russian is perfect.

As a last resort I can translate it message by message, but it would be less consistent.
victzh is offline Find More Posts by victzh
Reply With Quote
Old Dec 17, 2012, 09:20 PM
Registered User
RW9UAO's Avatar
Russian Federation, Kemerovskaya oblast, Kemerovo
Joined Dec 2012
61 Posts
about DSMX lost signal i see later. write on a paper and think some.
for telemetry. it`s really easy, take logic analizer/oscill and you will see.

TM1000, oscill channel 1(yellow) - IRQ line form CYRF to PSoC: first 8 bytes received in buffer, next full 16 bytes packet. after 4 ms we see thecond packet, after him we see transmit (osc chan 2), ending of transmit acknoledge by interrupt to.


another time sec/div
again 8 bytes interrupt, next full buffer interrupt. after 500 usec transmit goes on, ending after 800 uSec interrupt.
telemetry transmit on same channel of receive. and same CRC_SEED/SOP/DATA

in dsmX telemetry use 7 ms pause for TX, use same times (like dsm2) and same channel like receiver.

in a binding telemetry module receive answer from RX to transmitter and store work mode (0x01, 0x02, 0xA2, 0xB2, etc). after this (led off) receiver scan band, a looking for two channles (dsm2) or generate channel list (dsmX). ok, they found channels (receiver and tm led power on), transmit only zeroes packet. on the transmitter screen we see "telemetry" in binding mode. after some time TM put real info in a packet. let me show some working sources. PSoC, orange 6 channel receiver.
Code:
#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules
#include "main.h"

unsigned char const pncodes[5][9][8] = {
    /* Note these are in order transmitted (LSB 1st) */
{ /* Row 0 */
  /* Col 0 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8},
  /* Col 1 */ {0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6},
  /* Col 2 */ {0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9},
  /* Col 3 */ {0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4},
  /* Col 4 */ {0x8C, 0xFA, 0x47, 0x9B, 0x83, 0xA5, 0x66, 0xD0},
  /* Col 5 */ {0x07, 0xBD, 0x9F, 0x26, 0xC8, 0x31, 0x0F, 0xB8},
  /* Col 6 */ {0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D},
  /* Col 7 */ {0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1},
  /* Col 8 */ {0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86}
},
{ /* Row 1 */
  /* Col 0 */ {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3},
  /* Col 1 */ {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9},
  /* Col 2 */ {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82},
  /* Col 3 */ {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB},
  /* Col 4 */ {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7},
  /* Col 5 */ {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95},
  /* Col 6 */ {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4},
  /* Col 7 */ {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF},
  /* Col 8 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97}
},
{ /* Row 2 */
  /* Col 0 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97},
  /* Col 1 */ {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA},
  /* Col 2 */ {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE},
  /* Col 3 */ {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD},
  /* Col 4 */ {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD},
  /* Col 5 */ {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9},
  /* Col 6 */ {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3},
  /* Col 7 */ {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0},
  /* Col 8 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E}
},
{ /* Row 3 */
  /* Col 0 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E},
  /* Col 1 */ {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7},
  /* Col 2 */ {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1},
  /* Col 3 */ {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4},
  /* Col 4 */ {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6},
  /* Col 5 */ {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80},
  /* Col 6 */ {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88},
  /* Col 7 */ {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88},
  /* Col 8 */ {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40}
},
{ /* Row 4 */
  /* Col 0 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93},
  /* Col 1 */ {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C},
  /* Col 2 */ {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA},
  /* Col 3 */ {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC},
  /* Col 4 */ {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84},
  /* Col 5 */ {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7},
  /* Col 6 */ {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0},
  /* Col 7 */ {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1},
  /* Col 8 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8}
},
};
unsigned char const pn_bind[] = { 0x98,0x88,0x1b,0xe4,0x30,0x79,0x03,0x84 };
//=================================================================================================
void CYRF_init(char bind){
unsigned char temp;
//13c0:		//RST pin
PRT0DR |= 0x10;
for(temp = 0; temp < 20; temp++)asm("nop");
PRT0DR &= ~0x10;
for(temp = 0; temp < 20; temp++)asm("nop");

	CYRF_write(0x9D, 0x01);//  - wr MODE_OVERRIDE_ADR = RST
	for(temp = 0; temp < 20; temp++)asm("nop");
	CYRF_write(0xA8, 0x02);//  - wr CLK_EN_ADR = RXF
	CYRF_write(0xB2, 0x3C);//  - wr AUTO_CAL_TIME_ADR = 0x3C
	CYRF_write(0xB5, 0x14);//  - wr AUTO_CAL_OFFSET_ADR = 0x14
	temp = CYRF_read(0x0D);//  - rd IO_CFG_ADR
	CYRF_write(0x8D, temp | 0x40);//  - wr IO_CFG_ADR = IRQ POL	; Set IRQ polarity to positive.	
	temp = CYRF_read(0x0D);//  - rd IO_CFG_ADR
	temp &= ~0x10;//XOUT as GPIO
	CYRF_write(0x0D, temp | 0x04); //From Devo - Enable PACTL as GPIO
	CYRF_write(0x0E, 0x00); //From Devo
	CYRF_write(0x86, 0x48);//  - wr RX_CFG_ADR = LNA | FAST TURN EN
	CYRF_write(0x9B, 0x55);//  - wr TX_OFFSET_LSB_ADR
	CYRF_write(0x9C, 0x05);//  - wr TX_OFFSET_MSB_ADR
	CYRF_write(0x8F, 0x2C);//  - wr XACT_CFG_ADR = FRC END | Synth Mode (RX) 
	CYRF_write(0x83, 0x3F);//  - wr TX_CFG_ADR = 64 chip codes | SDR Mode | +4 dBm

	CYRF_write(0x92, 0x0E);//  - wr DATA64_THOLD_ADR = 0x0E 
	CYRF_write(0x0C, 0xC0);//  - wr XTAL_CTRL_ADR XTAL - GPIO
	CYRF_write(0x8F, 0x0C);//  - wr XACT_CFG_ADR = Synth Mode (RX)
//146d:
	if(bind){
		CYRF_write(0x83, 0x3F);//TX_CFG_ADR = 64 chip codes | SDR Mode | +4 dBm
		CYRF_write(0x90, 0x4A);//FRAMING_CFG_ADR = SOP LEN 64 chips | SOP TH = 0xA
		CYRF_write(0x9E, 0x14);//RX_OVERRIDE_ADR = FRC RXDR | DIS RXCRC
		CYRF_write(0x94, 0x02);//EOP_CTRL_ADR = EOP = 0x02
		CYRF_write(0x9F, 0x04);//TX_OVERRIDE_ADR = DIS TXCRC
		CYRF_write_block_const(0xA3, &pncodes[0][8][0], 8);
		CYRF_write_block_const(0xA3, &pn_bind[0], 8);
	}else{
		CYRF_write(0x83, 0x0F);// - wr TX_CFG_ADR = 32 chip codes, 8DR Mode, +4 dBm,
		CYRF_write(0x90, 0xEE);//  - wr FRAMING_CFG_ADR = SOP EN | SOP LEN | LEN EN | SOP TH = 0x0E
		CYRF_write(0x9F, 0x00);//  - wr TX_OVERRIDE_ADR
		CYRF_write(0x9E, 0x00);//  - wr RX_OVERRIDE_ADR
	}
}
//=================================================================================================
void CYRF_write(unsigned char reg, unsigned char value){
	M8C_SetBank0;
	SS_Data_ADDR &= ~SS_MASK;
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
	SPIM_1_SendTxData(reg | 0x80);
	/* Ensure the transmit buffer is free */  
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
	SPIM_1_SendTxData(value);
	/* Ensure the transmit buffer is free */  
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_SPI_COMPLETE ) );
	M8C_SetBank0;
	SS_Data_ADDR |= SS_MASK;
}
//=================================================================================================
unsigned char CYRF_read(unsigned char reg){
unsigned char value;
	M8C_SetBank0;
	SS_Data_ADDR &= ~SS_MASK;
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
	SPIM_1_SendTxData(reg);
	/* Ensure the transmit buffer is free */  
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
	SPIM_1_SendTxData(0x00);
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_RX_BUFFER_FULL ) );
	value = SPIM_1_bReadRxData();
	M8C_SetBank0;
	SS_Data_ADDR |= SS_MASK;
return value;
}
//=================================================================================================
void CYRF_read_block(unsigned char reg, unsigned char *pbStrPtr, unsigned char len){
	M8C_SetBank0;
	SS_Data_ADDR &= ~SS_MASK;
	reg &= ~0x80;	//read mode
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
	SPIM_1_SendTxData(reg);
	/* Ensure the transmit buffer is free */  
	while(len){
		while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
		SPIM_1_SendTxData(0x00);
		while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_RX_BUFFER_FULL ) );
		*pbStrPtr = SPIM_1_bReadRxData();
		pbStrPtr++;
		len--;
	}
	M8C_SetBank0;
	SS_Data_ADDR |= SS_MASK;
}
//=================================================================================================
void CYRF_write_block(unsigned char reg, unsigned char *pbStrPtr, unsigned char len){
	M8C_SetBank0;
	SS_Data_ADDR &= ~SS_MASK;
	reg |= 0x80;	//write mode
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
	SPIM_1_SendTxData(reg);
	/* Ensure the transmit buffer is free */  
	while(len){
		while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
		SPIM_1_SendTxData(*pbStrPtr);
		pbStrPtr++;
		len--;
	}
	M8C_SetBank0;
	SS_Data_ADDR |= SS_MASK;
}
//=================================================================================================
void CYRF_write_block_const(unsigned char reg, const unsigned char *pbStrPtr, unsigned char len){
	M8C_SetBank0;
	SS_Data_ADDR &= ~SS_MASK;
	reg |= 0x80;	//write mode
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
	SPIM_1_SendTxData(reg);
	/* Ensure the transmit buffer is free */  
	while(len){
		while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY ) );
		SPIM_1_SendTxData(*pbStrPtr);
		pbStrPtr++;
		len--;
	}
	while( ! (SPIM_1_bReadStatus() & SPIM_1_SPIM_SPI_COMPLETE ) );
	M8C_SetBank0;
	SS_Data_ADDR |= SS_MASK;
}
//=================================================================================================
void receive(unsigned char channel, unsigned char ch){
unsigned char rx_irq_status=0;
unsigned char row;
unsigned char i, temp;
unsigned int temp_int = 0;

	if(ch != 3){				//if no BIND mode
		row = channel % 5;

		if(ch){
			CYRF_write(0x15, CRC_SEED & 0xFF);
			CYRF_write(0x16, CRC_SEED >> 8);
		}else{
			CYRF_write(0x15, ~(CRC_SEED & 0xFF));
			CYRF_write(0x16, ~(CRC_SEED >> 8));
		}
		CYRF_write_block_const(0xA2, &pncodes[row][sop_col][0], 8);		// load SOP
		CYRF_write_block_const(0xA3, &pncodes[row][data_col][0], 8);	//load DATA
		CYRF_write_block_const(0xA3, &pncodes[row][data_col+1][0], 8);
	}
	
	CYRF_write(0x80, channel);//  - wr CHANNEL_ADR
RadioStartReceive:
	CYRF_write(0x85, 0x83);//  - wr RX_CTRL_ADR = RX GO | RXC IRQEN | RXE IRQEN 
	rssi = CYRF_read(0x13);//  - rd RSSI_ADR 
	
	CYRF_write(0x0E, 0x80);//XOUT = high	
//ждем пока не произойдет прерывание
	if(ch == 3)tcount = 25; // 12 mSec
	else tcount = 94; //24 mSec
	tflag = 1;// устанавливаем флаг	
	do{
		if(PRT0DR & 0x40){ tflag = 0; tcount = 0;}
	}while( tflag );

	CYRF_write(0x0E, 0x00);//XOUT = low
	
	if(PRT0DR & 0x40){		//прерывание было
		rssi = CYRF_read(0x13);//  - rd RSSI_ADR 
RadioGetReceiveStateIsr:
		rx_irq_status = CYRF_read(0x07);

//был принят пакет
		if(rx_irq_status & RXC){
			LED_Data_ADDR &= ~LED_MASK;	//ON
			error_counter = ERROR_C;
RadioEndReceive:
			if(ch == 3){				//BIND
				tcount = 10; tflag = 1;
				do{						//подождем немного, вдруг прийдут все 16 байт
					rx_count = CYRF_read(0x09);// - rd RX_COUNT_ADR
					if(rx_count == 0x10) tflag = 0; tcount = 0;
				}while(tflag);
			}else{							// normal mode
				rx_count = CYRF_read(0x09);// - rd RX_COUNT_ADR
			}
			
			if(rx_count && ch == 3){
				channelA = channel;// что-то приняли в бинде
			}
//в режиме бинда сначала вычитаем принятый пакет			
			if(ch == 3){
				CYRF_read_block(0x21, RXbuffer, 0x10);//получим принятый пакет в буфер
			}
#ifdef TX_ENABLE
			if(rx_count == 0x10 && ch == 0){
				for(i=0;i<100;i++)asm("nop");
				CYRF_write(0x0E, 0x80 | 0x20);//XOUT and PACTL - high
				CYRF_write(0x02, 0x40); //TX_CTRL_ADR = TX CLR				
				CYRF_write_block(0x20, TXbuffer, 0x10);
				CYRF_write(0x01, 0x10); //TX_LENGTH_ADR
				CYRF_write(0x02, 0x82); //TX_CTRL_ADR
//подождем пока все уйдет
				tcount = 20; // 0,5 mSec
				tflag = 1;// устанавливаем флаг
				do{
					if(CYRF_read(0x04) & 0x02){ tflag = 0; tcount = 0;}
				}while( tflag );
				
				CYRF_write(0x0E,0x00);//all GPIO - low
			}
#endif
//в обычном режиме вычитаем буфер после передачи пакета телеметрии
			if(ch != 3){
				CYRF_read_block(0x21, RXbuffer, 0x10);//получим принятый пакет в буфер
			}

//режим BIND, принят полный пакет, нужные байтики совпали
//нужно подсчитать CRC, забьем пока
			if(rx_count == 0x10 && ch == 3 &&
				RXbuffer[0] == RXbuffer[4] && RXbuffer[2] == RXbuffer[6] &&
				RXbuffer[0] != RXbuffer[1] && RXbuffer[1] != RXbuffer[2] ){
				
				// загружаем это и ждем ответ приемника длиной 10 байт, из него берем тип приемника
				// по умолчанию DSM2 (1024/22 mSec)
				//CYRF_write_block_const(0xA3, &pn_bind[0], 8);// 1760: 	lcall 063b
				
				//save manufacturer ID and model match
				mnfctID[0] = 0xFF - RXbuffer[0];
				mnfctID[1] = 0xFF - RXbuffer[1];
				mnfctID[2] = 0xFF - RXbuffer[2]; 
				mnfctID[3] = 0xFF - RXbuffer[3];//model match
				#ifdef DEBUG
					TX8_1_CPutString("Bind RX ok 0x");
					TX8_1_PutSHexByte(RXbuffer[0]);TX8_1_PutSHexByte(RXbuffer[1]);
					TX8_1_PutSHexByte(RXbuffer[2]);TX8_1_PutSHexByte(RXbuffer[3]);
					TX8_1_PutCRLF();
				#endif
				channelB = channelA = channel;
			}
//конец приема		
			CYRF_write(0x8F, 0x2C);// - wr XACT_CFG_ADR = FRC END | Synth Mode (RX) 
			while(CYRF_read(0x0F) & 0x20 );//подождем пока флаг FRC END сбросится

			//-------------------------------------------
			#ifdef DEBUG
				//if(ch == 3){
				if( channelB==0xFF || channelA==0xFF){
					TX8_1_PutSHexByte(channel); TX8_1_PutChar(' ');
					TX8_1_PutSHexByte(rssi); TX8_1_PutChar(' ');
					TX8_1_PutSHexByte(rx_irq_status); TX8_1_PutChar(' ');
					TX8_1_PutSHexByte(CYRF_read(0x04)); TX8_1_PutChar(' ');//TX_IRQ_STATUS_ADR
					TX8_1_PutSHexByte(rx_count); TX8_1_PutChar('[');
					for(i = 0; i < rx_count; i++){
						TX8_1_PutSHexByte(RXbuffer[i]);
						if( (i < rx_count-1) && (i%2) )TX8_1_PutChar('-');
					}
					TX8_1_PutChar(']');
					TX8_1_PutCRLF();
				}
			#endif			
			//-------------------------------------------		
			if(ch){
			//с разными CRC_SEED но с одним каналом все равно правильный прием
			//следим за флагами SOP_DET и RX_ERR
				if( channelB==0xFF && !(rx_irq_status & 0x01) && RXbuffer[0]==(0xFF - mnfctID[2]) && rx_count == 0x10 && rssi & 0x80 ){
					if( channelA != channel ){
						channelB = channel;
						#ifdef DEBUG
							TX8_1_PutSHexByte(channel);TX8_1_PutChar('b');TX8_1_PutCRLF();
						#endif
					}
				}
			}else{
				if( channelA==0xFF && !(rx_irq_status & 0x01) && RXbuffer[0]==(0xFF - mnfctID[2]) && rx_count == 0x10 && rssi & 0x80 ){
					if (channelB != channel){
						channelA = channel;
						#ifdef DEBUG
							TX8_1_PutSHexByte(channel);TX8_1_PutChar('a');TX8_1_PutCRLF();
						#endif
					}
				}
			}			
		}else{//была ошибка приема	
			CYRF_write(0xA9, 0x20);// - wr RX_ABORT_ADR = ABORT EN
			//пауза нужна небольшая
			LED_Data_ADDR |= LED_MASK;//OFF
			if(error_counter)error_counter--;
			CYRF_write(0xA9, 0x00);// - wr RX_ABORT_ADR			
		}
	}else{//не было прерывания
		CYRF_write(0xA9, 0x20);// - wr RX_ABORT_ADR = ABORT EN
		CYRF_write(0x8F, 0x2C);// - wr XACT_CFG_ADR = FRC END | Synth Mode (RX) 
		while(CYRF_read(0x0F) & 0x20 );
		CYRF_write(0xA9, 0x00);// - wr RX_ABORT_ADR
		LED_Data_ADDR |= LED_MASK;//OFF
		if(error_counter)error_counter--;
	
		//BIND, если ранее было принято что-то, но перестало приниматься
		if(ch == 3 && channelA != 0xFF && channelB == 0xFF)channelA = 0xFF;
	}
	CYRF_write(0x0E,0x00);//all GPIO - low
}//=================================================================================================
void scan(void){
unsigned char i;
//сканируем все каналы
channelA = 0xFF; channelB = 0xFF;
	while(channelA == 0xFF || channelB == 0xFF){
		for(i = 1; i < 0x50; i++){
			receive(i, 0);
			if(channelA != 0xFF && channelB != 0xFF)return;//exit if channels found
			receive(i, 1);
			if(channelA != 0xFF && channelB != 0xFF)return;//exit if channels found
			if(i%8)LED_Data_ADDR &= ~LED_MASK;	//ON
		}
	}
}
//=================================================================================================
Code:
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
//#pragma interrupt_handler MyTimerISR
/*
P0[0] - MISO CYRF6936
P0[1] - вход UART сателлита
P0[3] - SCK CYRF6936
P0[5] - MOSI CYRF6936
P0[6] - IRQ CYRF6936
P0[7] - SS CYRF6936

P1[0] - RUDD - DATA pgm
P1[1] - AILE - SCLK pgm
P1[4] - GEAR - volts
P1[5] - ELEV - RxV
P1[6] - AUX1 - amps
P1[7] - THRO - RPM

P3[0] - LED
P3[2] - BIND - UART i/o
*/

#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules
#include "main.h"

unsigned char channelA = 0xFF, channelB = 0xFF, rx_count = 0, rssi = 0;
unsigned int CRC_SEED;
unsigned char RXbuffer[0x10], TXbuffer[0x10];
unsigned char tflag = 0, tcount = 0, tm = 0, RPM_counter = 0;
unsigned int seconds = 0, sec_counter = 0;
//telemetry values
unsigned char RPM = 0;
unsigned int volts = 0, RxV = 0x200, amps = 0, mAh1 = 0, bat2 = 0;
unsigned char mnfctID[4], sop_col, data_col;
unsigned char ADC_chan = 0;
unsigned char error_counter = ERROR_C;
//====================================================================
void mAh_counter(void){
//float temp_float;
unsigned int temp_float;
			temp_float = amps;
			temp_float = temp_float * 1000;//А в мА
			temp_float = temp_float / 60;
			temp_float = temp_float / 60;// это сколько мА сожрал за 1 секунду
			mAh1 = mAh1 + temp_float;// это сколько сожрал всего
}
//====================================================================
void get_adc(void){
unsigned int temp_int;
unsigned long temp_long;
//	спросим АЦП

	switch(ADC_chan){
	case 0:
		MUX_CR1 |= 0x01;//P1[0] - RUDD - 
	break;
	case 1:
		MUX_CR1 |= 0x02;//P1[1] - AILE - 
	break;
	case 2:
		MUX_CR1 |= 0x10;//P1[4] - GEAR - volts
	break;
	case 3:
		MUX_CR1 |= 0x20;//P1[5] - ELEV - RxV
	break;
	case 4:
		MUX_CR1 |= 0x40;//P1[6] - AUX1 - amps
	break;
	}//end sw
	
	ADC10_1_StartADC();                  // Begin sampling
/*Note: When multiplexing between inputs of the ADC, the first sample on a new input may not be valid.
To ensure that the first reading on a new channel is valid, the ADC can either be stopped and restarted
between samples or the first sample on the channel may be discarded.
*/
	temp_int = ADC10_1_iGetDataClearFlag();		
	while(0 == ADC10_1_fIsDataAvailable());
	temp_int = ADC10_1_iGetDataClearFlag();		
	while(0 == ADC10_1_fIsDataAvailable());
		
		switch(ADC_chan){
		case 0:
			temp_int = ADC10_1_iGetDataClearFlag();
			ADC_chan++;
		break;
		case 1:
			temp_int = ADC10_1_iGetDataClearFlag();
			ADC_chan++;
		break;
		case 2:
			volts = ADC10_1_iGetDataClearFlag();
			#ifdef DEBUG
				//TX8_1_CPutString(" 0x");TX8_1_PutSHexInt(volts);
			#endif
			if(volts > FULLADC)volts = FULLADC;
			// 3 мВ на 1 бит АЦП, получим мВ. прибавим 50 для округления и переведем в десятки мВ
			volts = volts * 3;
			//volts = volts + 50;
			volts *= 11;//делитель 6k8:68k
			volts = volts / 10;
			ADC_chan++;
		break;
		case 3:
			temp_int = ADC10_1_iGetDataClearFlag();
			if(temp_int > FULLADC)temp_int = FULLADC;
			RxV = temp_int * 3;
			RxV = RxV * 4;//делитель 1k:3k
			RxV += 50;//округление
			RxV = RxV / 10;
			ADC_chan++;
		break;
		case 4:
			temp_int = ADC10_1_iGetDataClearFlag();
			amps = ADC10_1_iGetDataClearFlag();
			if(amps > FULLADC)amps = FULLADC;
			#ifdef DEBUG
				//TX8_1_CPutString(" 0x");TX8_1_PutSHexInt(amps);
			#endif
			temp_long = FULLADC - amps;
			temp_long = temp_long * 300;// mV. добавим к-т 100
			temp_long = temp_long / 40;//40 мВ на 1 Ампер
			bat2 = temp_long;
			//amps += 50;//для округления 0.5
			amps = temp_long / 100;// уберем к-т 100
			ADC_chan = 0;
		break;
		default:
			ADC_chan = 0;
		}//end sw
	
	ADC10_1_StopADC();
	MUX_CR1 &= ~(0x01 | 0x02 | 0x10 | 0x20 | 0x40);
}
//====================================================================
void main(void){
unsigned char i, packet_counter = 0xFF;
unsigned char temp;
unsigned char RX8buff[16], RX8buff_c=0, bRxStatus;
unsigned int temp_int;

M8C_EnableGInt;      // разрешение глобальных прерываний

Timer8_1_WritePeriod(39); //for 256,75 uSec int
Timer8_1_EnableInt();   // разрешение прерывания таймера
Timer8_1_Start();

//TX8_1_DisableInt();
//TX8_1_Start(TX8_PARITY_NONE);

//RX8_1_EnableInt();
//RX8_1_Start(RX8_PARITY_NONE);//9600
//RX8_1_CmdReset();

SPIM_1_DisableInt();
SPIM_1_Start(SPIM_1_SPIM_MODE_0 | SPIM_1_SPIM_MSB_FIRST);

E2PROM_Start();

//TX8_1_CPutString("CYRF\r\n");

//Bit5 in the INT_MSK0 bit is the Mask bit for GPIO interrupt.
//Only when this bit is set, the interrupts raised by GPIO pins will be processed by the CPU
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);
	// Clear the SplitMux bit in DAC_CR register.  This will connect the Left and Right
	// Mux buses into a single Mux bus.  Now, any pin can be connected to the Mux
	// bus through the MUX_CRx register
DAC_CR &= ~0x80;
MUX_CR1 = 0x40;							//P1[6] - AUX1 - amps
ADC10_1_Start(ADC10_1_FULLRANGE);     	// full range = 832
ADC10_1_iCal(433, ADC10_1_CAL_VBG);  	// 1.3V = 433 counts 
ADC10_1_StartADC();                  	// Begin sampling

E2PROM_E2Read(0, mnfctID, 4);
//если ЕЕПРОМ пустой, будем использовать мой mnfctID
//if(mnfctID[0] == 0 && mnfctID[1] == 0 && mnfctID[2] == 0 && mnfctID[3] == 0){
//	mnfctID[0] = 0x6d; mnfctID[1] = 0x39; mnfctID[2] = 0xa7;
//}

if(!(PRT3DR & 0x04)){//перемычка BIND вставлена
//	mnfctID[0] = 0; mnfctID[1] = 0; mnfctID[2] = 0; mnfctID[3] = 0;

	#ifdef DEBUG
		TX8_1_CPutString("bind\r\n");
	#endif
	CYRF_init(1);// bind mode
	packet_counter = 0;//потом будет ожидание передачи БИНД пакета телеметрии
	for(i=0;i<0x10;i++)TXbuffer[i]=0;//подготовим буфер передачи BIND пакета
	while(channelA == 0xFF || channelB == 0xFF){
		for(i = 1; i < 0x50; i+=2){
			if(channelA != 0xFF && channelB == 0xFF){
				receive(channelA, 3);//что-то было на этом канале, повторим
			}else{
				receive(i, 3);
			}
			if(channelA != 0xFF && channelB != 0xFF)i=0x7f;//exit if channels found
		}
	}
	E2PROM_bE2Write(0, mnfctID, 4, 20);
}
#ifdef DEBUG
	TX8_1_CPutString("normal\r\n");
#endif
CYRF_init(0);// normal mode
//calculate only once
sop_col = (mnfctID[0] + mnfctID[1] + mnfctID[2] + 2) & 7;
data_col = 7 - sop_col;
CRC_SEED = ~((mnfctID[0] << 8) + mnfctID[1]); 
		
scan();

while(1){
	receive(channelA, 0);// - пауза между каналами 4 мсек
	receive(channelB, 1);//	 - тут будет передача телеметрии
	//далее большая пауза

	if(error_counter == 0)scan();

	//если был BIND, то посылаем пустые пакеты
	if(packet_counter < 100){
		packet_counter++;
		tm = 0xFF;//Это чтобы state machine не писала ничего в пакет
		//пакет из одних 0x00 применяется при бинде
	}

#ifdef TX_ENABLE	
	//подготовим буфер передачи
	switch(tm){
		case 0:	//0x7F - A,B,L,R,F,H,RxV,RSSI
		case 2:
		case 4:
		case 6:
			TXbuffer[0] = 0x7F; TXbuffer[1]=0x00;
			TXbuffer[2]=0x00; TXbuffer[3]=0x00;
			TXbuffer[4]=0x00; TXbuffer[5]=0x00;
			TXbuffer[6]=0x7F; TXbuffer[7]=0xFF;//RSSI
			TXbuffer[8]=0x00; TXbuffer[9]=0x00;
			TXbuffer[10]=0x00; TXbuffer[11]=0x00;
			TXbuffer[12]=0x00; TXbuffer[13]=0x00;
			TXbuffer[14] = RxV >> 8; TXbuffer[15] = RxV & 0xFF;//RxV
			//temp_int = amps * 10;
			//TXbuffer[14] = temp_int >> 8; TXbuffer[15] = temp_int & 0xFF;
			tm++;
			break;
		case 1://0x7E - volts, rpm, temp
			TXbuffer[0] = 0x7E; TXbuffer[1]=0x00;
			TXbuffer[2] = RPM;
			TXbuffer[3]=0x00;
			temp_int = volts + 5;//округление
			TXbuffer[4] = temp_int >>8; TXbuffer[5] = temp_int & 0xFF;
			TXbuffer[6]=0x00; TXbuffer[7]=0x00;//temp
			TXbuffer[8]=0x00; TXbuffer[9]=0x00;
			TXbuffer[10]=0x00; TXbuffer[11]=0x00;
			TXbuffer[12]=0x00; TXbuffer[13]=0x00;
			TXbuffer[14]=0x00; TXbuffer[15]=0x00;//
			tm++;
			break;
		case 3://0x03 - Amps
			TXbuffer[0] = 0x03; TXbuffer[1]=0x00;
			temp_int = amps * 0x103;
			temp_int = temp_int / 50;//50 Ампер покажет если передать 0x103
			TXbuffer[2] = temp_int >>8; TXbuffer[3] = temp_int & 0xFF;
			TXbuffer[4]=0x00; TXbuffer[5]=0x00;
			TXbuffer[6]=0x00; TXbuffer[7]=0x00;
			TXbuffer[8]=0x00; TXbuffer[9]=0x00;
			TXbuffer[10]=0x00; TXbuffer[11]=0x00;
			TXbuffer[12]=0x00; TXbuffer[13]=0x00;
			TXbuffer[14]=0x00; TXbuffer[15]=0x00;//
			tm++;
			break;
		case 5://0x11 - Speed
			TXbuffer[0] = 0x11; TXbuffer[1]=0x00;
			TXbuffer[2]=0x00; TXbuffer[3]=0x00;
			TXbuffer[4]=0x00; TXbuffer[5]=0x00;
			TXbuffer[6]=0x00; TXbuffer[7]=0x00;
			TXbuffer[8]=0x00; TXbuffer[9]=0x00;
			TXbuffer[10]=0x00; TXbuffer[11]=0x00;
			TXbuffer[12]=0x00; TXbuffer[13]=0x00;
			TXbuffer[14]=0x00; TXbuffer[15]=0x00;//
			tm++;
			break;
		case 7://0x0A - PowerBox
			TXbuffer[0] = 0x0A; TXbuffer[1]=0x00;
			TXbuffer[2] = volts >>8; TXbuffer[3] = volts & 0xFF;//battery1
			TXbuffer[4] = bat2 >>8; TXbuffer[5] = bat2;//battery2
			TXbuffer[6] = mAh1 >>8; TXbuffer[7] = mAh1 & 0xFF;//cap1
			TXbuffer[8]=0x00; TXbuffer[9]=0x00;//cap2
			TXbuffer[10]=0x00; TXbuffer[11]=0x00;
			TXbuffer[12]=0x00; TXbuffer[13]=0x00;
			TXbuffer[14]=0x00; TXbuffer[15]=0x00;//
			tm++;
			break;
		case 8://0x12 - Alt
			TXbuffer[0] = 0x12; TXbuffer[1]=0x00;
			TXbuffer[2]=0x00; TXbuffer[3]=0x00;
			TXbuffer[4]=0x00; TXbuffer[5]=0x00;
			TXbuffer[6]=0x00; TXbuffer[7]=0x00;
			TXbuffer[8]=0x00; TXbuffer[9]=0x00;
			TXbuffer[10]=0x00; TXbuffer[11]=0x00;
			TXbuffer[12]=0x00; TXbuffer[13]=0x00;
			TXbuffer[14]=0x00; TXbuffer[15]=0x00;//
			tm++;
			break;
		case 9://ADC
			get_adc();
			tm = 0;
			break;
		default:
			tm = 0;
		break;		
	}//end switch
#endif
		
	if(rx_count == 0){
		LED_Data_ADDR |= LED_MASK;//OFF
	}
/*
	temp_int = RX8_1_iReadChar()>> 8;
	if( temp_int == 0 || temp_int == RX8_RX_NO_ERROR ){
		LED_Data_ADDR |= LED_MASK;//OFF
		do{
			TXbuffer[RX8buff_c++] = RX8_1_cGetChar();
		}while(RX8buff_c < 16);
		RX8buff_c = 0;
	}
*/

}//end while(1)

}//end main
RW9UAO is offline Find More Posts by RW9UAO
Reply With Quote
Old Dec 18, 2012, 04:18 AM
Registered User
Joined May 2011
655 Posts
Brilliant! Thank you very much!
A code worth thousand words...

About the recovery after a signal loss:
I think the receiver simply continues to listen to the channels in the calculated order. That's how PB and printk discovered the sequence: they've sent only the binding package, and then watched which channels the receiver had choosed.
So if they get out of sync, I guess the game is over...
FDR_ is offline Find More Posts by FDR_
Reply With Quote
Old Dec 18, 2012, 05:44 AM
Registered User
RW9UAO's Avatar
Russian Federation, Kemerovskaya oblast, Kemerovo
Joined Dec 2012
61 Posts
next, dsmX lost signal i see on the SPI bus between CYRF and PSoC.
if channel list indexed from 0 to 22, channels scan on index:
unsigned char jump_table = [9, 10, 8, 11, 7, 12, 6, 13, 5, 14, 4, 15, 3, 16, 2, 17, 1, 18, 0, 19, 22, 20, 21];
scan in a both directions. from 0 to 22, and back from 22 to 0 in jump_table. try.

i check only one model, my AR8000 damaged.
RW9UAO is offline Find More Posts by RW9UAO
Reply With Quote
Old Dec 18, 2012, 06:04 AM
Registered User
Joined May 2011
655 Posts
Looks interesting. Why they do not start at the middle of the channel count I wonder...
Do they use this same sequence wherever the communication was lost?

I've paired the two sequence in the possible 23 ways, and in 8 cases of the total 23 they won't find each other again!

EDIT: ...at least within one whole sequence. I will check if it will match later if things go on the same way....

EDIT2: Yep, they will definitely find each other in the second round the latest...
FDR_ is offline Find More Posts by FDR_
Last edited by FDR_; Dec 18, 2012 at 06:21 AM.
Reply With Quote
Old Dec 18, 2012, 06:57 AM
Registered User
Joined May 2011
655 Posts
It needs minimum 1 try, and maximum 42 tries to find each other again.
The avarage is 17...

It means, that the recovery may take 42*11ms=462ms, if I'm right!
FDR_ is offline Find More Posts by FDR_
Reply With Quote
Old Dec 18, 2012, 07:18 AM
Registered User
UK
Joined Aug 2000
1,082 Posts
23 is an odd number so I think you need to take inverting CRC into account. If you get a CRC error, use same CRC state and next freq in sequence for next receive in 4-18ms time.
dt.
David T is offline Find More Posts by David T
Reply With Quote
Old Dec 18, 2012, 07:40 AM
Registered User
Joined May 2011
655 Posts
I think it is not about loosing one frame, since then the tx and rx would stay in sync, and they could continue on the next frequency, but about loosing sync, for example if the rx restarts. Am I right?
FDR_ is offline Find More Posts by FDR_
Reply With Quote
Old Dec 18, 2012, 07:52 AM
Registered User
UK
Joined Aug 2000
1,082 Posts
I find it helpful to write 2 or 3 sequences of the 23 freq pattern down on paper, put the time between each and whether the CRC is normal or inverted. I then ask myself 'if I sit on freq1 until I get a hit but perhaps with errors, why might that be, so where am I in the sequence, and what is the best freq/crc state/timeout to try next'.
dt.
David T is offline Find More Posts by David T
Reply With Quote
Old Dec 18, 2012, 08:51 AM
Registered User
Joined May 2011
655 Posts
Well, I did almost that: tried to pair the normal sequence with RW9UAO's one, and just looked for matching channels.
I ignored the CRC's this time...

Do you suggest, that even if the CRC is wrong at the first time when the channels are equal, you can assume that you are back on trail, just one sequence off?

Anyway, with cheking the CRCs, the time to resync should be just even longer, shouldn't it?


EDIT: Sorry about my english, I might just misunderstood something...
FDR_ is offline Find More Posts by FDR_
Last edited by FDR_; Dec 18, 2012 at 09:04 AM.
Reply With Quote
Old Dec 18, 2012, 09:11 AM
Registered User
RW9UAO's Avatar
Russian Federation, Kemerovskaya oblast, Kemerovo
Joined Dec 2012
61 Posts
CRC in received packet check fast. look to RX_IRQ_STATUS_ADR from CYRF. when CRC good - 0x7A, when CRC bad - 0x7B. bit 0 need you. next look RX_STATUS_ADR look to bit 3.
bad CRC_SEED is not a great problem. really you need check manufacturerID in a begin of packet. a forget about CRC_SEED and check RXE, well, work good.

i have only one tric - in the BINDing mode i read DATA register file, in transmit mode i have not time, i transmit and after them load receive bytes.
RW9UAO is offline Find More Posts by RW9UAO
Reply With Quote
Old Dec 18, 2012, 09:11 AM
Registered User
Joined Jan 2012
682 Posts
Quote:
Originally Posted by FDR_ View Post
Well, I did almost that: tried to pair the normal sequence with RW9UAO's one, and just looked for matching channels.
I ignored the CRC's this time...

Do you suggest, that even if the CRC is wrong at the first time when the channels are equal, you can assume that you are back on trail, just one sequence off?

Anyway, with cheking the CRCs, the time to resync should be just even longer, shouldn't it?
You can't actually tell if you received any data when the CRC is wrong. The CYRF6936 will indicate a data-error if the CRC data doesn't match (I think, I've never actually verified this behavior). So getting the CRC wrong is basically the same as receiving junk. So baisclaly assume 46 channels instead of 23. Or read RW9UAO's post, and find out I'm wrong)

So you can either sit on one channel waiting for data (46 packets at 1 packet per 11msec (or 2 packets per 11msec for >7 channels => 506/253msec to rebind)
I think (but didn't do the math) it ends up taking at least the same time if you scan through the channels (probably even longer since you could miss the channel while changing), but the benefit is that you are much less susceptible to collisions from another radio.
PhracturedBlue is offline Find More Posts by PhracturedBlue
Reply With Quote
Old Dec 18, 2012, 09:15 AM
Registered User
UK
Joined Aug 2000
1,082 Posts
Do you have a firm understanding of what the Tx is sending out? If not you need to work that out paying attention to the freq order, timing and whether the CRC is normal or inverted. Because 23 is an odd number, you need 2 repeats of the 23 freq to have the whole pattern.
Regards, David.
David T is offline Find More Posts by David T
Reply With Quote
Old Dec 18, 2012, 09:18 AM
Registered User
RW9UAO's Avatar
Russian Federation, Kemerovskaya oblast, Kemerovo
Joined Dec 2012
61 Posts
Quote:
3C BF 7A B8 10[A7F6-0C04-2956-13DE-1BDC-3156-FFFF-FFFF]
3E BF 7B B8 10[A7F6-0C02-2956-13DE-1BDD-3156-FFFF-FFFF]
look, i set one value for CRC_SEED, correct value for SOP/DATA (based on channel num and manufacturerID). i receive good packet info, not garbage =) if channel is empty, you have not interrupt (IRQ) for a time-out. check RX_IRQ_STATUS_ADR and RX_STATUS_ADR.
RW9UAO is offline Find More Posts by RW9UAO
Reply With Quote
Reply


Thread Tools

Similar Threads
Category Thread Thread Starter Forum Replies Last Post
Sold DSMX DX-8 and (2) DSMX Sats for Sale laughingstill Aircraft - General - Radio Equipment (FS/W) 3 Jan 20, 2012 11:24 AM
Wanted JR9503 DSMX or JR 11X DSMX and AR9200/AR9210 Receiver w/sats patrick21x Aircraft - General - Radio Equipment (FS/W) 0 Nov 17, 2011 10:22 PM
Discussion WALKERA 2.4 TX hack -can YOU hack it? aaronstomfoolery Radios 2 Oct 29, 2011 04:44 AM
Sold NNIB AR6210 DSMX w/sat + AR600 DSMX GeetarJoe Aircraft - General - Radio Equipment (FS/W) 0 Oct 19, 2011 01:50 AM