-
-
Save ahmetserdar/be1343dde518945f11e730fd415122d1 to your computer and use it in GitHub Desktop.
Test PTT from Si4463 on Fubarino mini https://github.com/seongyooncho/polarnstruments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftSPI.h> | |
/* | |
This code based from pecanpico6 Si446x Driver by KT5TK | |
https://github.com/tkrahn/pecanpico5a | |
*/ | |
/* | |
const static uint8_t SS = 30; // PIC32 SS2 | |
const static uint8_t MOSI = 29; // PIC32 SDO2 | |
const static uint8_t MISO = 27; // PIC32 SDI2 | |
const static uint8_t SCK = 4; // PIC32 SCK2 | |
*/ | |
#define RF_GP1 3 | |
#define RF_NIRQ 0 | |
#define RF_SCK SCK | |
#define RF_MISO MISO | |
#define RF_MOSI MOSI | |
#define RF_NSEL SS | |
#define RF_GP3 2 | |
#define RF_SDN 26 | |
#define LED1 PIN_LED1 | |
#define LED2 25 | |
SoftSPI spi; | |
void Si4463_reset() | |
{ | |
// Reset Radio(POR) | |
digitalWrite(RF_SDN, HIGH); | |
delay_us(10); | |
digitalWrite(RF_SDN, LOW); | |
} | |
void Si4463_send(int command_byte_size, uint8_t * command_bytes) | |
{ | |
// Set Slave Select | |
spi.setSelect(HIGH); | |
delay_us(10); | |
spi.setSelect(LOW); | |
spi.transfer(command_byte_size, command_bytes); | |
// Set Slave Select | |
spi.setSelect(HIGH); | |
delay_us(20); | |
spi.setSelect(LOW); | |
// Wait CTS | |
int reply = 0x00; | |
while (reply != 0xFF) | |
{ | |
spi.transfer(0x44); | |
reply = spi.transfer(0x44); | |
Serial.print(reply, HEX); | |
Serial.print(" "); | |
if (reply != 0xFF) | |
{ | |
spi.setSelect(HIGH); | |
delay_us(10); | |
spi.setSelect(LOW); | |
} | |
} | |
spi.setSelect(HIGH); | |
delay_ms(50); | |
} | |
void Si4463_radio_boot() | |
{ | |
// Waiting GP1=HIGH for 5ms for POR | |
do { | |
delay_ms(5); | |
} while (digitalRead(RF_GP1) == LOW); | |
// PowerUP | |
#define VCXO_FREQ 30000000L | |
// 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); | |
uint8_t init_command[] = {0x02, 0x01, 0x01, x3, x2, x1, x0};// no patch, boot main app. img, FREQ_VCXO, return 1 byte | |
Si4463_send(7, init_command); | |
} | |
void Si4463_radio_ready() | |
{ | |
// clear all pending interrupts | |
uint8_t get_int_status_command[] = {0x20, 0x00, 0x00, 0x00}; // Clear all pending interrupts and get the interrupt status back | |
Si4463_send(4, get_int_status_command); | |
} | |
int outdiv = 4; | |
unsigned int si446x_powerlevel = 0; | |
unsigned long active_shift = 400; | |
unsigned int active_level = 20; | |
void Si4463_set_frequency(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; // | |
uint8_t set_band_property_command[] = {0x11, 0x20, 0x01, 0x51, (band + sy_sel)}; // | |
// send parameters | |
Si4463_send(5, 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 | |
uint8_t set_frequency_property_command[] = {0x11, 0x40, 0x06, 0x00, n, m2, m1, m0, c1, c0}; | |
// send parameters | |
Si4463_send(10, set_frequency_property_command); | |
// Set the Power | |
uint8_t set_pa_pwr_lvl_property_command[] = {0x11, 0x22, 0x01, 0x01, active_level}; | |
// send parameters | |
Si4463_send(5, set_pa_pwr_lvl_property_command); | |
} | |
void Si4463_set_modem() | |
{ | |
// Set to CW mode | |
uint8_t set_modem_mod_type_command[] = {0x11, 0x20, 0x01, 0x00, 0x00}; | |
Si4463_send(5, set_modem_mod_type_command); | |
} | |
void Si4463_tune_tx() { | |
uint8_t change_state_command[] = {0x34, 0x05}; // Change to TX tune state | |
Si4463_send(2, change_state_command); | |
} | |
void Si4463_ptt_off() { | |
// Set Power 0(MIN) | |
uint8_t power = 0; | |
uint8_t set_pa_power_command[] = {0x11, 0x22, 0x01, 0x01, power}; | |
Si4463_send(5, set_pa_power_command); | |
// TURN RF Switch as TX | |
// uPG2214TB RF Switch turn TX RF_GP0=LOW, RF_GP2=HIGH | |
uint8_t gpio_pin_cfg_command[] = {0x13, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}; // Set GPIO0 as LOW, GPIO2 as HIGH. all other GPIOs do not modify; NIRQ do not modify;SDO do not modify; Max drive strength | |
Si4463_send(8, gpio_pin_cfg_command); | |
// start tx | |
uint8_t change_state_command[] = {0x34, 0x07}; // Change to TX state | |
Si4463_send(2, change_state_command); | |
} | |
void Si4463_ptt_on() | |
{ | |
digitalWrite(RF_SDN, LOW); | |
// Set Power 127(MAX) | |
uint8_t power = 127; | |
uint8_t set_pa_power_command[] = {0x11, 0x22, 0x01, 0x01, power}; | |
Si4463_send(5, set_pa_power_command); | |
// TURN RF Switch as TX | |
// uPG2214TB RF Switch turn TX RF_GP0=LOW, RF_GP2=HIGH | |
uint8_t gpio_pin_cfg_command[] = {0x13, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}; // Set GPIO0 as LOW, GPIO2 as HIGH. all other GPIOs do not modify; NIRQ do not modify;SDO do not modify; Max drive strength | |
Si4463_send(8, gpio_pin_cfg_command); | |
// start tx mode | |
uint8_t change_state_command[] = {0x34, 0x07}; // Change to TX state | |
Si4463_send(2, change_state_command); | |
} | |
void setup() | |
{ | |
// Serial | |
Serial.begin(9600); | |
// Setup GPIO | |
pinMode(LED1, OUTPUT); | |
pinMode(RF_GP1, INPUT); | |
pinMode(RF_NIRQ, INPUT); | |
pinMode(RF_SDN, OUTPUT); | |
// Turn off Si4463 | |
digitalWrite(RF_SDN, HIGH); | |
// Setup SPI | |
spi.begin(RF_NSEL, RF_MOSI, RF_MISO, RF_SCK); | |
//spi.begin(); | |
spi.setSpeed(250000); // 250khz | |
spi.setMode(SSPI_MODE0); | |
//spi.setDirection(SSPI_SHIFT_LEFT); // MSB | |
spi.setSelect(HIGH); // Do not select a slave | |
Serial.println("Start Serial"); | |
// Reset Radio | |
Si4463_reset(); | |
// Radio Boot | |
Si4463_radio_boot(); | |
// Radio Ready and Set GPIO, Frequency, Mode | |
Si4463_radio_ready(); | |
Si4463_set_frequency(460000000UL); | |
Si4463_set_modem(); | |
// Set Tune TX | |
Si4463_tune_tx(); | |
// Start TX | |
Si4463_ptt_on(); | |
} | |
void loop() | |
{ | |
Si4463_ptt_on(); | |
digitalWrite(LED1, HIGH); | |
delay(1000); | |
Si4463_ptt_off(); | |
digitalWrite(LED1, LOW); | |
delay(1000); | |
} | |
void delay_ms(long tick) | |
{ | |
delay_us(tick * 1000); | |
} | |
void delay_us(long tick) | |
{ | |
volatile int cnt; | |
for (cnt = 0; cnt < tick*10; cnt++) { | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment