Пример #1
0
void RadioSi446x::start_tx()
{
// W2CXM Debug - overwrite power level  
  char set_pa_power_lvl_command[] = {0x11, 0x22, 0x01, 0x01, 0x7f};
  SendCmdReceiveAnswer(5, 1, set_pa_power_lvl_command);
  
  
  char change_state_command[] = {0x34, 0x07}; //  Change to TX state
  SendCmdReceiveAnswer(2, 1, change_state_command);

}
Пример #2
0
// Config reset ----------------------------------------------------------
void RadioSi446x::reset(void) 
{
  digitalWrite(VCXO_ENABLE_PIN,HIGH);
//  Serial.println("VCXO is enabled"); 
  delay(200);
  
  

  digitalWrite(RADIO_SDN_PIN, HIGH);  // active high shutdown = reset
  delay(200);
  digitalWrite(RADIO_SDN_PIN, LOW);   // booting
//  Serial.println("Radio is powered up"); 

  // Start talking to the Si446X radio chip

  const char PART_INFO_command[] = {0x01}; // Part Info
  SendCmdReceiveAnswer(1, 9, PART_INFO_command);
//  Serial.println("Part info was checked");

//divide VCXO_FREQ into its bytes; MSB first  
  unsigned int x3 = VCXO_FREQ / 0x1000000;
  unsigned int x2 = (VCXO_FREQ - x3 * 0x1000000) / 0x10000;
  unsigned int x1 = (VCXO_FREQ - x3 * 0x1000000 - x2 * 0x10000) / 0x100;
  unsigned int x0 = (VCXO_FREQ - x3 * 0x1000000 - x2 * 0x10000 - x1 * 0x100); 

//POWER_UP
  const char init_command[] = {0x02, 0x01, 0x01, x3, x2, x1, x0};// no patch, boot main app. img, FREQ_VCXO, return 1 byte
  SendCmdReceiveAnswer(7, 1 ,init_command); 

//  Serial.println("Radio booted"); 

  const char get_int_status_command[] = {0x20, 0x00, 0x00, 0x00}; //  Clear all pending interrupts and get the interrupt status back
  SendCmdReceiveAnswer(4, 9, get_int_status_command);


//  Serial.println("Radio ready");
 
  const char gpio_pin_cfg_command[] = {0x13, 0x02, 0x02, 0x02, 0x02, 0x08, 0x11, 0x00}; //  Set all GPIOs LOW; Link NIRQ to CTS; Link SDO to MISO; Max drive strength
  SendCmdReceiveAnswer(8, 8, gpio_pin_cfg_command);

//  Serial.println("LEDs should be switched off at this point");
  
  setFrequency(active_freq);
//  Serial.println("Frequency set");  
 
  setModem(); 
//  Serial.println("CW mode set");  
  
  tune_tx();
//  Serial.println("TX tune");  



}
Пример #3
0
void reset(void) {
	gpio_set_value(RADIO_SDN, 1);
	mdelay(10);
	gpio_set_value(RADIO_SDN, 0);
	mdelay(10);
	u8 buff[10];
//POWER_UP
/*
	printk(KERN_ALERT "Set CS to 1 \n");
	cs_high();
	printk(KERN_ALERT "get CS %d \n",gpio_get_value(SSpin));
	mdelay(5000);
	printk(KERN_ALERT "Set CS to 0 \n");
	cs_low();
	printk(KERN_ALERT "get CS %d \n",gpio_get_value(SSpin));
	mdelay(5000);
	printk(KERN_ALERT "Set CS to 1 \n");
	cs_high();
	printk(KERN_ALERT "get CS %d \n",gpio_get_value(SSpin));
	mdelay(5000);
	printk(KERN_ALERT "Set CS to 0 \n");
	cs_low();
	printk(KERN_ALERT "get CS %d \n",gpio_get_value(SSpin));
*/
//const unsigned char init_command[] = {0x02, 0x01, 0x01, x3, x2, x1, x0};// no patch, boot main app. img, FREQ_VCXO, return 1 byte
	u8 init_command[] = { RF_POWER_UP };
	SendCmdReceiveAnswer(7, 1, init_command, buff);
	mdelay(20);
	//ppp(buff, 1);
	SendCmdReceiveAnswer(7, 1, init_command, buff);
	mdelay(20);

	u8 PART_INFO_command[] = { 0x01 }; // Part Info
	SendCmdReceiveAnswer(1, 9, PART_INFO_command, buff);
	//ppp(buff, 9);

	u8 get_int_status_command[] = { 0x20, 0x00, 0x00, 0x00 }; //  Clear all pending interrupts and get the interrupt status back
	SendCmdReceiveAnswer(4, 9, get_int_status_command, buff);
	//ppp(buff, 9);

//const char gpio_pin_cfg_command[] = {0x13, 0x02, 0x02, 0x02, 0x02, 0x08, 0x11, 0x00}; //  Set all GPIOs LOW; Link NIRQ to CTS; Link SDO to MISO; Max drive strength
//	u8 gpio_pin_cfg_command[] = { 0x13, 0x14, 0x02, 0x21, 0x20,
//			0x27, 0x0b, 0x00 };
//	SendCmdReceiveAnswer(8, 8, gpio_pin_cfg_command, buff);
//	//ppp(buff, 8);
//

	setRFParameters();
	fifo_reset();

}
Пример #4
0
void Si446x::sendFrequencyToSi446x(unsigned long freq)
{
  // Set the output divider according to recommended ranges given in Si446x datasheet  
  int band = 0;
  if (freq < 705000000UL) { outdiv = 6;  band = 1;};
  if (freq < 525000000UL) { outdiv = 8;  band = 2;};
  if (freq < 353000000UL) { outdiv = 12; band = 3;};
  if (freq < 239000000UL) { outdiv = 16; band = 4;};
  if (freq < 177000000UL) { outdiv = 24; band = 5;};
  
 
  unsigned long f_pfd = 2 * VCXO_FREQ / outdiv;
  
  unsigned int n = ((unsigned int)(freq / f_pfd)) - 1;
  
  float ratio = (float)freq / (float)f_pfd;
  float rest  = ratio - (float)n;
  

  unsigned long m = (unsigned long)(rest * 524288UL); 
 


// set the band parameter
  unsigned int sy_sel = 8; // 
  char set_band_property_command[] = {0x11, 0x20, 0x01, 0x51, (band + sy_sel)}; //   
  // send parameters
  SendCmdReceiveAnswer(5, 1, set_band_property_command);

// Set the pll parameters
  unsigned int m2 = m / 0x10000;
  unsigned int m1 = (m - m2 * 0x10000) / 0x100;
  unsigned int m0 = (m - m2 * 0x10000 - m1 * 0x100); 
  
  unsigned long channel_increment = 524288 * outdiv * active_shift / (2 * VCXO_FREQ);
  char c1 = channel_increment / 0x100;
  char c0 = channel_increment - (0x100 * c1);
  
  // assemble parameter string
  char set_frequency_property_command[] = {0x11, 0x40, 0x06, 0x00, n, m2, m1, m0, c1, c0};
  // send parameters
  SendCmdReceiveAnswer(10, 1, set_frequency_property_command);
  
  // Set the Power
  char set_pa_pwr_lvl_property_command[] = {0x11, 0x22, 0x01, 0x01, active_level};
  // send parameters
  SendCmdReceiveAnswer(5, 1, set_pa_pwr_lvl_property_command);
  

}
Пример #5
0
//u8 test[300];
//void spi_write_fifo(unsigned char * data, int len) {
//	int j;
///*
////	test[0] = WRITE_TX_FIFO;
////	memcpy(test+1, data, len);
////	mutex_lock(&mutex_spi);
////	printk(KERN_ALERT "spi_write_fifo: write %d\n", len);
//	cs_low();
//	u8 cmd = WRITE_TX_FIFO;
//	spidev_global.buffer = &cmd;
//	spidev_sync_write(&spidev_global, 1);
////	for (j = 0; j < len; j++) {
////		cmd = data[j];
////		spidev_sync_write(&spidev_global, 1);
////	}
//	spidev_global.buffer = data;
//	spidev_sync_write(&spidev_global, len);
//	cs_high();
//
////	mutex_unlock(&mutex_spi);
// */
//	ssize_t ret;
//	u8 cmd = WRITE_TX_FIFO;
//	struct spi_transfer	t_cmd = {
//			.tx_buf		= &cmd,
//			.len		= 1,
//		};
//	struct spi_transfer	t_data = {
//			.tx_buf		= data,
//			.len		= len,
//		};
//	struct spi_message	m;
//
//	spi_message_init(&m);
//	spi_message_add_tail(&t_cmd, &m);
//	spi_message_add_tail(&t_data, &m);
//	ret = spidev_sync(spidev_global, &m);
//}
void spi_write_fifo(unsigned char * data, int len) {
	int j;
	ssize_t ret;
	u8 cmd = 0x66;
	struct spi_transfer	t_cmd = {
			.tx_buf		= &cmd,
			.len		= 1,
			.cs_change 	= 0,
		};
	struct spi_transfer	t_data = {
			.tx_buf		= data,
			.len		= len,
			.cs_change 	= 0,
		};
	struct spi_message	m;

	spi_message_init(&m);
	spi_message_add_tail(&t_cmd, &m);
	spi_message_add_tail(&t_data, &m);
	cs_low();
	ret = spidev_sync(&spidev_global, &m);
	cs_high();
}

void spi_read_fifo(unsigned char * st, int len) {
	int j;

//	mutex_lock(&mutex_spi);

	cs_low();
	u8 cmd = READ_RX_FIFO;
//	u8 ret;
	spidev_global.buffer = &cmd;
	spidev_sync_write(&spidev_global, 1);
	cmd = 0xff;

//	for (j = 0; j < len; j++) {
//		spidev_sync_transfer(&spidev_global, &cmd, &(st[j]),  1);
//
//	}
	spidev_global.buffer = st;
	spidev_sync_read(&spidev_global,len);
	cs_high();
//	mutex_unlock(&mutex_spi);

	//Serial.println();
	//  unsigned char p[] = {READ_RX_FIFO};
	//  SendCmdReceiveAnswer(1,payload_length,p);
}

void get_fifo_info(u8 *rx)			// 复位发射和接收 FIFO
{
//	u8 rx[10];
	unsigned char p[2];

	p[0] = FIFO_INFO;
	p[1] = 0x00;
	SendCmdReceiveAnswer(2, 3, p, rx);
	//	spi_write(2,p);
}
Пример #6
0
void get_ph_status(u8 *rx){
	unsigned char p[2];

	p[0] = GET_PH_STATUS;
	p[1] = 0xfb;
	SendCmdReceiveAnswer(2, 3, p, rx);
}
Пример #7
0
void get_modem_status(u8 *rx){
	unsigned char p[2];

	p[0] = GET_MODEM_STATUS;
	p[1] = 0xff;
	SendCmdReceiveAnswer(2, 4, p, rx);
}
Пример #8
0
u8 get_device_state(){
	u8 p[2], rx[2];
	p[0] = REQUEST_DEVICE_STATE;
	p[1] = 0x00;
	SendCmdReceiveAnswer(2, 3, p, rx);
	return rx[1];
}
Пример #9
0
void Si446x::start_tx(char channel)
{
//  char change_state_command[] = {0x34, 0x07}; //  Change to TX state
//  SendCmdReceiveAnswer(2, 1, change_state_command);
  //tune_tx();
  char start_tx_command[] = {0x31, channel, 0x30, 0x00, 0x00, 0x00};
  SendCmdReceiveAnswer(6, 1, start_tx_command);
}
Пример #10
0
void RadioSi446x::setModem()
{
  // Set to CW mode
//  Serial.println("Setting modem into CW mode");  
  char set_modem_mod_type_command[] = {0x11, 0x20, 0x01, 0x00, 0x00};
  SendCmdReceiveAnswer(5, 1, set_modem_mod_type_command);
  
}
Пример #11
0
void RadioSi446x::setFrequency(unsigned long freq)
{ 
  
  // Set the output divider according to recommended ranges given in Si446x datasheet  
  int outdiv = 4;
  int band = 0;
  if (freq < 705000000UL) { outdiv = 6;  band = 1;};
  if (freq < 525000000UL) { outdiv = 8;  band = 2;};
  if (freq < 353000000UL) { outdiv = 12; band = 3;};
  if (freq < 239000000UL) { outdiv = 16; band = 4;};
  if (freq < 177000000UL) { outdiv = 24; band = 5;};
  
 
  unsigned long f_pfd = 2 * VCXO_FREQ / outdiv;
  
  unsigned int n = ((unsigned int)(freq / f_pfd)) - 1;
  
  float ratio = (float)freq / (float)f_pfd;
  float rest  = ratio - (float)n;
  

  unsigned long m = (unsigned long)(rest * 524288UL); 
 


// set the band parameter
  unsigned int sy_sel = 8; // 
  char set_band_property_command[] = {0x11, 0x20, 0x01, 0x51, (band + sy_sel)}; //   
  // send parameters
  SendCmdReceiveAnswer(5, 1, set_band_property_command);

// Set the pll parameters
  unsigned int m2 = m / 0x10000;
  unsigned int m1 = (m - m2 * 0x10000) / 0x100;
  unsigned int m0 = (m - m2 * 0x10000 - m1 * 0x100); 
  // assemble parameter string
  //char set_frequency_property_command[] = {0x11, 0x40, 0x04, 0x00, n, m2, m1, m0};
  // send parameters
  //SendCmdReceiveAnswer(8, 1, set_frequency_property_command);
  
  //W2CXM - suggestions from aadamson
  const char set_freq_control_inte[] = {0x11, 0x40, 0x08, 0x00, n, m2, m1, m0, 0x0B, 0x61, 0x20, 0xFA};
  SendCmdReceiveAnswer(12, 1, set_freq_control_inte);
  //W2CXM ^^^^
}
Пример #12
0
void Si446x::setModem()
{
  // Set to CW mode
  //Serial.println("Setting modem into direct asynchronous 2FSK mode using GPIO0");  
  char set_modem_mod_type_command[] = {0x11, 0x20, 0x01, 0x00, 0b10001010};
  SendCmdReceiveAnswer(5, 1, set_modem_mod_type_command);
  
  
}
Пример #13
0
void clr_packet_rx_pend(void) {
	u8 p[2];
	u8 p2[3];
	p[0] = GET_PH_STATUS;
//	p[1] = 0xef;
	p[1] = 0x20;//leave the PACKET_SENT_PEND_CLR alone
//	spi_write_cmd(2, p);
	SendCmdReceiveAnswer(2,3,p,p2);
}
Пример #14
0
void RadioSi446x::ptt_off()
{
  stop_tx();
  si446x_powerlevel = 0;
  // turn off the blue LED (GPIO2)
  char gpio_pin_cfg_command0[] = {0x13, 0x02, 0x02, 0x02, 0x02, 0x08, 0x0b, 0x00}; //  Set all GPIOs LOW; Link NIRQ to CTS; Link SDO to MISO; Max drive strength
  SendCmdReceiveAnswer(8, 1, gpio_pin_cfg_command0);

  digitalWrite(RADIO_SDN_PIN, HIGH);  // active high = shutdown
  //digitalWrite(VCXO_ENABLE_PIN, LOW); //keep enabled for now

}
Пример #15
0
void RadioSi446x::ptt_on()
{
  
  digitalWrite(VCXO_ENABLE_PIN, HIGH);
  reset();
  // turn on the blue LED (GPIO2) to indicate TX
  char gpio_pin_cfg_command2[] = {0x13, 0x02, 0x02, 0x03, 0x02, 0x08, 0x0b, 0x00}; //  Set GPIO2 HIGH; Link NIRQ to CTS; Link SDO to MISO; Max drive strength
  SendCmdReceiveAnswer(8, 1, gpio_pin_cfg_command2);

  start_tx();
  si446x_powerlevel = 1023;
}
Пример #16
0
void get_interrupt_status(u8* p2)		// 中断
{
	unsigned char p[4];

	p[0] = GET_INT_STATUS;
	p[1] = 0xfb;
	p[2] = 0x7f;
	p[3] = 0x7f;
	SendCmdReceiveAnswer(4,9,p,p2);
//	spi_write_cmd(4, p);
	//spi_read(9,GET_INT_STATUS);
}
Пример #17
0
//u16 get_packet_info()
//{
//	unsigned char p[6];
//	unsigned char p2[3];
//	u16 bLen;
//
//	p[0] = CMD_PACKET_INFO;
//	p[1] = 0x00;
//	p[2] = 0x00;
//	p[3] = 0x00;
//	p[4] = 0x00;
//	p[5] = 0x00;
//	SendCmdReceiveAnswer(1,3,p,p2);
//	bLen = ((u16)p2[1] << 8) | (u16)p2[2];
//	return bLen;
//}
u8 get_packet_info(void) {
  unsigned char p[3];
  unsigned char p2[3];
  p[0] = PACKET_INFO ;
//  p[1] = 0x00 ; 			// 通道0
//  p[2] = 0x00;
//  p[3] = 0x00;
//  p[4] = 0x00;
//  p[5] = 0x00;

  SendCmdReceiveAnswer(1, 3, p, p2);
//  ppp(p2,3);
  return p2[2];
}
Пример #18
0
void Si446x::setDeviation(unsigned long deviation)
{
  //Make sure that Si446x::sendFrequencyToSi446x() was called before this function, so that we have set the global variable 'outdiv' properly
  //outdiv = 8;
  float units_per_hz = (( 0x40000 *  outdiv ) / (float)VCXO_FREQ);
  // Set deviation for RTTY
  unsigned long modem_freq_dev = (unsigned long)(units_per_hz * deviation / 2.0 );
  unsigned long mask = 0b11111111;
  char modem_freq_dev_0 = mask & modem_freq_dev;
  char modem_freq_dev_1 = mask & (modem_freq_dev >> 8);
  char modem_freq_dev_2 = mask & (modem_freq_dev >> 16);
  
  
  char set_modem_freq_dev_command[] = {0x11, 0x20, 0x03, 0x0A, modem_freq_dev_2, modem_freq_dev_1, modem_freq_dev_0};
  SendCmdReceiveAnswer(7, 1, set_modem_freq_dev_command);  
  
  
  
}
Пример #19
0
void RadioSi446x::tune_tx()
{
  char change_state_command[] = {0x34, 0x05}; //  Change to TX tune state
  SendCmdReceiveAnswer(2, 1, change_state_command);

}
Пример #20
0
void RadioSi446x::stop_tx()
{
  char change_state_command[] = {0x34, 0x03}; //  Change to Ready state
  SendCmdReceiveAnswer(2, 1, change_state_command);

}
Пример #21
0
// Config reset ----------------------------------------------------------
void RadioSi446x::reset(void) 
{
  digitalWrite(VCXO_ENABLE_PIN,HIGH);
//  Serial.println("VCXO is enabled"); 
  delay(200);
  
  

  digitalWrite(RADIO_SDN_PIN, HIGH);  // active high shutdown = reset
  delay(200);
  digitalWrite(RADIO_SDN_PIN, LOW);   // booting
//  Serial.println("Radio is powered up"); 

  // Start talking to the Si446X radio chip

  const char PART_INFO_command[] = {0x01}; // Part Info
  SendCmdReceiveAnswer(1, 9, PART_INFO_command);
//  Serial.println("Part info was checked");

//W2CXM - Suggested that we add this delay by aadmson
  delay(15);

//divide VCXO_FREQ into its bytes; MSB first  
  unsigned int x3 = VCXO_FREQ / 0x1000000;
  unsigned int x2 = (VCXO_FREQ - x3 * 0x1000000) / 0x10000;
  unsigned int x1 = (VCXO_FREQ - x3 * 0x1000000 - x2 * 0x10000) / 0x100;
  unsigned int x0 = (VCXO_FREQ - x3 * 0x1000000 - x2 * 0x10000 - x1 * 0x100); 

//POWER_UP
  const char init_command[] = {0x02, 0x01, 0x01, x3, x2, x1, x0};// no patch, boot main app. img, FREQ_VCXO, return 1 byte
  SendCmdReceiveAnswer(7, 1 ,init_command); 

//  Serial.println("Radio booted"); 

  const char get_int_status_command[] = {0x20, 0x00, 0x00, 0x00}; //  Clear all pending interrupts and get the interrupt status back
  SendCmdReceiveAnswer(4, 9, get_int_status_command);


//  Serial.println("Radio ready");
 
  const char gpio_pin_cfg_command[] = {0x13, 0x02, 0x02, 0x02, 0x02, 0x08, 0x0b, 0x00}; //  Set all GPIOs LOW; Link NIRQ to CTS; Link SDO to MISO; Max drive strength
  SendCmdReceiveAnswer(8, 8, gpio_pin_cfg_command);

// W2CXM - Added two more initializations per aadamson
  const char set_global_config1[] = {0x11, 0x00, 0x01, 0x03, 0x60};
  SendCmdReceiveAnswer(5, 1, set_global_config1);
  // cliPrint("Setting special global Config 1 changes (see WDS)\n");

  const char set_global_xo_tune_command[] = {0x11, 0x00, 0x01, 0x00, 0x00};
  SendCmdReceiveAnswer(5, 1, set_global_xo_tune_command);
  // cliPrint("Setting no additional capacitance on VXCO\n");
// W2CXM ^^^^^^^^^

//  Serial.println("LEDs should be switched off at this point");
  
  setFrequency(active_freq);
//  Serial.println("Frequency set");  
 
  setModem(); 
//  Serial.println("CW mode set");  
  
  tune_tx();
//  Serial.println("TX tune");  



}
Пример #22
0
u8 * spi_write_cmd(int byteCountTx, u8 * in_buff) {
	return SendCmdReceiveAnswer(byteCountTx, 0, in_buff, NULL);
}
Пример #23
0
void RadioSi446x::start_tx()
{
  char change_state_command[] = {0x34, 0x07}; //  Change to TX state
  SendCmdReceiveAnswer(2, 1, change_state_command);

}