First stage SI4463 RSSI working

Removed_REF_marker
erikkaashoek 5 years ago
parent e875c8f1ef
commit e2d5f52dc0

@ -247,7 +247,7 @@
PIN_MODE_ALTERNATE(GPIOB_I2C1_SCL) | \
PIN_MODE_ALTERNATE(GPIOB_I2C1_SDA) | \
PIN_MODE_OUTPUT(GPIOB_LO_SEL) | \
PIN_MODE_OUTPUT(11) | \
PIN_MODE_OUTPUT(GPIOB_SD_CS) | \
PIN_MODE_ALTERNATE(GPIOB_I2S2_WCLK) | \
PIN_MODE_ALTERNATE(GPIOB_I2S2_BCLK) | \
PIN_MODE_ALTERNATE(14) | \
@ -263,14 +263,14 @@
PIN_OTYPE_PUSHPULL(GPIOB_I2C1_SCL) | \
PIN_OTYPE_PUSHPULL(GPIOB_I2C1_SDA) | \
PIN_OTYPE_PUSHPULL(GPIOB_LO_SEL) | \
PIN_OTYPE_PUSHPULL(11) | \
PIN_OTYPE_PUSHPULL(GPIOB_SD_CS) | \
PIN_OTYPE_PUSHPULL(GPIOB_I2S2_WCLK) | \
PIN_OTYPE_PUSHPULL(GPIOB_I2S2_BCLK) | \
PIN_OTYPE_PUSHPULL(14) | \
PIN_OTYPE_PUSHPULL(GPIOB_I2S2_MOSI))
#define VAL_GPIOB_OSPEEDR (PIN_PUPDR_FLOATING(GPIOB_XN) | \
PIN_PUPDR_FLOATING(GPIOB_YN) | \
PIN_OSPEED_2M(GPIOB_RX_SEL) | \
PIN_OSPEED_100M(GPIOB_RX_SEL) | \
PIN_OSPEED_100M(3) | \
PIN_OSPEED_100M(4) | \
PIN_OSPEED_100M(5) | \
@ -278,8 +278,8 @@
PIN_OSPEED_100M(7) | \
PIN_OSPEED_100M(GPIOB_I2C1_SCL) | \
PIN_OSPEED_100M(GPIOB_I2C1_SDA) | \
PIN_OSPEED_2M(GPIOB_LO_SEL) | \
PIN_OSPEED_100M(11) | \
PIN_OSPEED_100M(GPIOB_LO_SEL) | \
PIN_OSPEED_100M(GPIOB_SD_CS) | \
PIN_OSPEED_100M(GPIOB_I2S2_WCLK) | \
PIN_OSPEED_100M(GPIOB_I2S2_BCLK) | \
PIN_OSPEED_100M(14) | \
@ -295,7 +295,7 @@
PIN_PUPDR_PULLUP(GPIOB_I2C1_SCL) | \
PIN_PUPDR_PULLUP(GPIOB_I2C1_SDA) | \
PIN_PUPDR_PULLUP(GPIOB_LO_SEL) | \
PIN_PUPDR_PULLUP(11) | \
PIN_PUPDR_PULLUP(GPIOB_SD_CS) | \
PIN_PUPDR_PULLUP(GPIOB_I2S2_WCLK) | \
PIN_PUPDR_PULLUP(GPIOB_I2S2_BCLK) | \
PIN_PUPDR_PULLUP(14) | \
@ -311,7 +311,7 @@
PIN_ODR_HIGH(GPIOB_I2C1_SCL) | \
PIN_ODR_HIGH(GPIOB_I2C1_SDA) | \
PIN_ODR_HIGH(GPIOB_LO_SEL) | \
PIN_ODR_HIGH(11) | \
PIN_ODR_HIGH(GPIOB_SD_CS) | \
PIN_ODR_HIGH(GPIOB_I2S2_WCLK) | \
PIN_ODR_HIGH(GPIOB_I2S2_BCLK) | \
PIN_ODR_HIGH(14) | \
@ -327,7 +327,7 @@
#define VAL_GPIOB_AFRH (PIN_AFIO_AF(GPIOB_I2C1_SCL, 4) | \
PIN_AFIO_AF(GPIOB_I2C1_SDA, 4) | \
PIN_AFIO_AF(GPIOB_LO_SEL, 0) | \
PIN_AFIO_AF(11, 0) | \
PIN_AFIO_AF(GPIOB_SD_CS, 0) | \
PIN_AFIO_AF(GPIOB_I2S2_WCLK, 5) | \
PIN_AFIO_AF(GPIOB_I2S2_BCLK, 5) | \
PIN_AFIO_AF(14, 0) | \
@ -355,7 +355,7 @@
PIN_MODE_INPUT(12) | \
PIN_MODE_OUTPUT(GPIOC_LED) | \
PIN_MODE_INPUT(14) | \
PIN_MODE_INPUT(15))
PIN_MODE_OUTPUT(15))
#define VAL_GPIOC_OTYPER (PIN_OTYPE_PUSHPULL(0) | \
PIN_OTYPE_PUSHPULL(1) | \
PIN_OTYPE_PUSHPULL(2) | \
@ -403,7 +403,7 @@
PIN_PUPDR_PULLUP(12) | \
PIN_PUPDR_FLOATING(GPIOC_LED) | \
PIN_PUPDR_FLOATING(14) | \
PIN_PUPDR_PULLUP(15))
PIN_PUPDR_FLOATING(15))
#define VAL_GPIOC_ODR (PIN_ODR_HIGH(0) | \
PIN_ODR_HIGH(1) | \
PIN_ODR_HIGH(2) | \

@ -0,0 +1,87 @@
#ifndef RADIO_CONFIG_H_
#define RADIO_CONFIG_H_
#define RF_POWER_UP 0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80
#define RF_GPIO_PIN_CFG 0x13, 0x41, 0x41, 0x21, 0x20, 0x67, 0x4B, 0x00
#define GLOBAL_2_0 0x11, 0x00, 0x04, 0x00, 0x52, 0x00, 0x18, 0x30
#define MODEM_2_0 0x11, 0x20, 0x0C, 0x00, 0x03, 0x00, 0x07, 0x02, 0x71, 0x00, 0x05, 0xC9, 0xC3, 0x80, 0x00, 0x00
#define MODEM_2_1 0x11, 0x20, 0x01, 0x0C, 0x46
#define MODEM_2_2 0x11, 0x20, 0x0C, 0x1C, 0x80, 0x00, 0xB0, 0x10, 0x0C, 0xE8, 0x00, 0x4E, 0x06, 0x8D, 0xB9, 0x00
#define MODEM_2_3 0x11, 0x20, 0x0A, 0x28, 0x00, 0x02, 0xC0, 0x08, 0x00, 0x12, 0xC6, 0xD4, 0x01, 0x5C
#define MODEM_2_4 0x11, 0x20, 0x0B, 0x39, 0x11, 0x11, 0x80, 0x1A, 0x20, 0x00, 0x00, 0x28, 0x0C, 0xA4, 0x23
#define MODEM_2_5 0x11, 0x20, 0x09, 0x45, 0x03, 0x00, 0x85, 0x01, 0x00, 0xFF, 0x06, 0x09, 0x10
#define MODEM_2_6 0x11, 0x20, 0x02, 0x50, 0x94, 0x0A
#define MODEM_2_7 0x11, 0x20, 0x02, 0x54, 0x03, 0x07
#define MODEM_2_8 0x11, 0x20, 0x05, 0x5B, 0x40, 0x04, 0x04, 0x78, 0x20
#define MODEM_CHFLT_2_0 0x11, 0x21, 0x0C, 0x00, 0x7E, 0x64, 0x1B, 0xBA, 0x58, 0x0B, 0xDD, 0xCE, 0xD6, 0xE6, 0xF6, 0x00
#define MODEM_CHFLT_2_1 0x11, 0x21, 0x0C, 0x0C, 0x03, 0x03, 0x15, 0xF0, 0x3F, 0x00, 0x7E, 0x64, 0x1B, 0xBA, 0x58, 0x0B
#define MODEM_CHFLT_2_2 0x11, 0x21, 0x0B, 0x18, 0xDD, 0xCE, 0xD6, 0xE6, 0xF6, 0x00, 0x03, 0x03, 0x15, 0xF0, 0x3F
#define PA_2_0 0x11, 0x22, 0x01, 0x03, 0x1D
#define FREQ_CONTROL_2_0 0x11, 0x40, 0x08, 0x00, 0x37, 0x09, 0x00, 0x00, 0x44, 0x44, 0x20, 0xFE
#define RF_START_RX 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
#define RF_IRCAL 0x17, 0x56, 0x10, 0xCA, 0xF0
#define RF_IRCAL_1 0x17, 0x13, 0x10, 0xCA, 0xF0
#define INT_CTL_5_0 0x11, 0x01, 0x04, 0x00, 0x07, 0x18, 0x00, 0x00
#define FRR_CTL_5_0 0x11, 0x02, 0x03, 0x00, 0x0A, 0x09, 0x00
#define PREAMBLE_5_0 0x11, 0x10, 0x01, 0x04, 0x31
#define SYNC_5_0 0x11, 0x11, 0x04, 0x01, 0xB4, 0x2B, 0x00, 0x00
#define PKT_5_0 0x11, 0x12, 0x0A, 0x00, 0x04, 0x01, 0x08, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x2A, 0x01
#define PKT_5_1 0x11, 0x12, 0x07, 0x0E, 0x01, 0x06, 0xAA, 0x00, 0x80, 0x02, 0x2A
#define MODEM_5_0 0x11, 0x20, 0x0A, 0x03, 0x1E, 0x84, 0x80, 0x09, 0xC9, 0xC3, 0x80, 0x00, 0x0D, 0xA7
#define MODEM_5_1 0x11, 0x20, 0x0B, 0x1E, 0x10, 0x20, 0x00, 0xE8, 0x00, 0x4B, 0x06, 0xD3, 0xA0, 0x06, 0xD4
#define MODEM_5_2 0x11, 0x20, 0x09, 0x2A, 0x00, 0x00, 0x00, 0x23, 0xC6, 0xD4, 0x00, 0xA9, 0xE0
#define MODEM_5_3 0x11, 0x20, 0x05, 0x39, 0x10, 0x10, 0x80, 0x1A, 0x40
#define MODEM_5_4 0x11, 0x20, 0x08, 0x46, 0x01, 0x15, 0x02, 0x00, 0x80, 0x06, 0x02, 0x18
#define MODEM_5_5 0x11, 0x20, 0x01, 0x50, 0x84
#define MODEM_5_6 0x11, 0x20, 0x01, 0x54, 0x04
#define MODEM_5_7 0x11, 0x20, 0x01, 0x5D, 0x08
#define MODEM_CHFLT_5_0 0x11, 0x21, 0x0C, 0x00, 0xA2, 0x81, 0x26, 0xAF, 0x3F, 0xEE, 0xC8, 0xC7, 0xDB, 0xF2, 0x02, 0x08
#define MODEM_CHFLT_5_1 0x11, 0x21, 0x0C, 0x0C, 0x07, 0x03, 0x15, 0xFC, 0x0F, 0x00, 0xA2, 0x81, 0x26, 0xAF, 0x3F, 0xEE
#define MODEM_CHFLT_5_2 0x11, 0x21, 0x0B, 0x18, 0xC8, 0xC7, 0xDB, 0xF2, 0x02, 0x08, 0x07, 0x03, 0x15, 0xFC, 0x0F
#define SYNTH_5_0 0x11, 0x23, 0x06, 0x00, 0x34, 0x04, 0x0B, 0x04, 0x07, 0x70
#define FREQ_CONTROL_5_0 0x11, 0x40, 0x04, 0x00, 0x38, 0x0D, 0xDD, 0xDD
#define RADIO_CONFIGURATION_DATA_ARRAY { \
0x07, RF_POWER_UP, \
0x08, RF_GPIO_PIN_CFG, \
0x08, GLOBAL_2_0, \
0x10, MODEM_2_0, \
0x05, MODEM_2_1, \
0x10, MODEM_2_2, \
0x0E, MODEM_2_3, \
0x0F, MODEM_2_4, \
0x0D, MODEM_2_5, \
0x06, MODEM_2_6, \
0x06, MODEM_2_7, \
0x09, MODEM_2_8, \
0x10, MODEM_CHFLT_2_0, \
0x10, MODEM_CHFLT_2_1, \
0x0F, MODEM_CHFLT_2_2, \
0x05, PA_2_0, \
0x0C, FREQ_CONTROL_2_0, \
0x08, RF_START_RX, \
0x05, RF_IRCAL, \
0x05, RF_IRCAL_1, \
0x08, INT_CTL_5_0, \
0x07, FRR_CTL_5_0, \
0x05, PREAMBLE_5_0, \
0x08, SYNC_5_0, \
0x0E, PKT_5_0, \
0x0B, PKT_5_1, \
0x0E, MODEM_5_0, \
0x0F, MODEM_5_1, \
0x0D, MODEM_5_2, \
0x09, MODEM_5_3, \
0x0C, MODEM_5_4, \
0x05, MODEM_5_5, \
0x05, MODEM_5_6, \
0x05, MODEM_5_7, \
0x10, MODEM_CHFLT_5_0, \
0x10, MODEM_CHFLT_5_1, \
0x0F, MODEM_CHFLT_5_2, \
0x0A, SYNTH_5_0, \
0x08, FREQ_CONTROL_5_0, \
}
#endif

@ -0,0 +1,87 @@
#ifndef RADIO_CONFIG_H_
#define RADIO_CONFIG_H_
#define RF_POWER_UP 0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80
#define RF_GPIO_PIN_CFG 0x13, 0x41, 0x41, 0x21, 0x20, 0x67, 0x4B, 0x00
#define GLOBAL_2_0 0x11, 0x00, 0x04, 0x00, 0x52, 0x00, 0x18, 0x30
#define MODEM_2_0 0x11, 0x20, 0x0C, 0x00, 0x03, 0x00, 0x07, 0x02, 0x71, 0x00, 0x05, 0xC9, 0xC3, 0x80, 0x00, 0x00
#define MODEM_2_1 0x11, 0x20, 0x01, 0x0C, 0x46
#define MODEM_2_2 0x11, 0x20, 0x0C, 0x1C, 0x80, 0x00, 0xB0, 0x10, 0x0C, 0xE8, 0x00, 0x4E, 0x06, 0x8D, 0xB9, 0x00
#define MODEM_2_3 0x11, 0x20, 0x0A, 0x28, 0x00, 0x02, 0xC0, 0x08, 0x00, 0x12, 0xC6, 0xD4, 0x01, 0x5C
#define MODEM_2_4 0x11, 0x20, 0x0B, 0x39, 0x11, 0x11, 0x80, 0x1A, 0x20, 0x00, 0x00, 0x28, 0x0C, 0xA4, 0x23
#define MODEM_2_5 0x11, 0x20, 0x09, 0x45, 0x03, 0x00, 0x85, 0x01, 0x00, 0xFF, 0x06, 0x09, 0x10
#define MODEM_2_6 0x11, 0x20, 0x02, 0x50, 0x94, 0x0A
#define MODEM_2_7 0x11, 0x20, 0x02, 0x54, 0x03, 0x07
#define MODEM_2_8 0x11, 0x20, 0x05, 0x5B, 0x40, 0x04, 0x04, 0x78, 0x20
#define MODEM_CHFLT_2_0 0x11, 0x21, 0x0C, 0x00, 0x7E, 0x64, 0x1B, 0xBA, 0x58, 0x0B, 0xDD, 0xCE, 0xD6, 0xE6, 0xF6, 0x00
#define MODEM_CHFLT_2_1 0x11, 0x21, 0x0C, 0x0C, 0x03, 0x03, 0x15, 0xF0, 0x3F, 0x00, 0x7E, 0x64, 0x1B, 0xBA, 0x58, 0x0B
#define MODEM_CHFLT_2_2 0x11, 0x21, 0x0B, 0x18, 0xDD, 0xCE, 0xD6, 0xE6, 0xF6, 0x00, 0x03, 0x03, 0x15, 0xF0, 0x3F
#define PA_2_0 0x11, 0x22, 0x01, 0x03, 0x1D
#define FREQ_CONTROL_2_0 0x11, 0x40, 0x08, 0x00, 0x37, 0x09, 0x00, 0x00, 0x44, 0x44, 0x20, 0xFE
#define RF_START_RX 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
#define RF_IRCAL 0x17, 0x56, 0x10, 0xCA, 0xF0
#define RF_IRCAL_1 0x17, 0x13, 0x10, 0xCA, 0xF0
#define INT_CTL_5_0 0x11, 0x01, 0x04, 0x00, 0x07, 0x18, 0x00, 0x00
#define FRR_CTL_5_0 0x11, 0x02, 0x03, 0x00, 0x0A, 0x09, 0x00
#define PREAMBLE_5_0 0x11, 0x10, 0x01, 0x04, 0x31
#define SYNC_5_0 0x11, 0x11, 0x04, 0x01, 0xB4, 0x2B, 0x00, 0x00
#define PKT_5_0 0x11, 0x12, 0x0A, 0x00, 0x04, 0x01, 0x08, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x2A, 0x01
#define PKT_5_1 0x11, 0x12, 0x07, 0x0E, 0x01, 0x06, 0xAA, 0x00, 0x80, 0x02, 0x2A
#define MODEM_5_0 0x11, 0x20, 0x0A, 0x03, 0x1E, 0x84, 0x80, 0x09, 0xC9, 0xC3, 0x80, 0x00, 0x0D, 0xA7
#define MODEM_5_1 0x11, 0x20, 0x0B, 0x1E, 0x10, 0x20, 0x00, 0xE8, 0x00, 0x4B, 0x06, 0xD3, 0xA0, 0x06, 0xD4
#define MODEM_5_2 0x11, 0x20, 0x09, 0x2A, 0x00, 0x00, 0x00, 0x23, 0xC6, 0xD4, 0x00, 0xA9, 0xE0
#define MODEM_5_3 0x11, 0x20, 0x05, 0x39, 0x10, 0x10, 0x80, 0x1A, 0x40
#define MODEM_5_4 0x11, 0x20, 0x08, 0x46, 0x01, 0x15, 0x02, 0x00, 0x80, 0x06, 0x02, 0x18
#define MODEM_5_5 0x11, 0x20, 0x01, 0x50, 0x84
#define MODEM_5_6 0x11, 0x20, 0x01, 0x54, 0x04
#define MODEM_5_7 0x11, 0x20, 0x01, 0x5D, 0x08
#define MODEM_CHFLT_5_0 0x11, 0x21, 0x0C, 0x00, 0xA2, 0x81, 0x26, 0xAF, 0x3F, 0xEE, 0xC8, 0xC7, 0xDB, 0xF2, 0x02, 0x08
#define MODEM_CHFLT_5_1 0x11, 0x21, 0x0C, 0x0C, 0x07, 0x03, 0x15, 0xFC, 0x0F, 0x00, 0xA2, 0x81, 0x26, 0xAF, 0x3F, 0xEE
#define MODEM_CHFLT_5_2 0x11, 0x21, 0x0B, 0x18, 0xC8, 0xC7, 0xDB, 0xF2, 0x02, 0x08, 0x07, 0x03, 0x15, 0xFC, 0x0F
#define SYNTH_5_0 0x11, 0x23, 0x06, 0x00, 0x34, 0x04, 0x0B, 0x04, 0x07, 0x70
#define FREQ_CONTROL_5_0 0x11, 0x40, 0x04, 0x00, 0x38, 0x0D, 0xDD, 0xDD
#define RADIO_CONFIGURATION_DATA_ARRAY { \
0x07, RF_POWER_UP, \
0x08, RF_GPIO_PIN_CFG, \
0x08, GLOBAL_2_0, \
0x10, MODEM_2_0, \
0x05, MODEM_2_1, \
0x10, MODEM_2_2, \
0x0E, MODEM_2_3, \
0x0F, MODEM_2_4, \
0x0D, MODEM_2_5, \
0x06, MODEM_2_6, \
0x06, MODEM_2_7, \
0x09, MODEM_2_8, \
0x10, MODEM_CHFLT_2_0, \
0x10, MODEM_CHFLT_2_1, \
0x0F, MODEM_CHFLT_2_2, \
0x05, PA_2_0, \
0x0C, FREQ_CONTROL_2_0, \
0x08, RF_START_RX, \
0x05, RF_IRCAL, \
0x05, RF_IRCAL_1, \
0x08, INT_CTL_5_0, \
0x07, FRR_CTL_5_0, \
0x05, PREAMBLE_5_0, \
0x08, SYNC_5_0, \
0x0E, PKT_5_0, \
0x0B, PKT_5_1, \
0x0E, MODEM_5_0, \
0x0F, MODEM_5_1, \
0x0D, MODEM_5_2, \
0x09, MODEM_5_3, \
0x0C, MODEM_5_4, \
0x05, MODEM_5_5, \
0x05, MODEM_5_6, \
0x05, MODEM_5_7, \
0x10, MODEM_CHFLT_5_0, \
0x10, MODEM_CHFLT_5_1, \
0x0F, MODEM_CHFLT_5_2, \
0x0A, SYNTH_5_0, \
0x08, FREQ_CONTROL_5_0, \
}
#endif

@ -0,0 +1,445 @@
/*
* Project: Si4463 Radio Library for AVR and Arduino
* Author: Zak Kemble, contact@zakkemble.co.uk
* Copyright: (C) 2017 by Zak Kemble
* License: GNU GPL v3 (see License.txt)
* Web: http://blog.zakkemble.co.uk/si4463-radio-library-avr-arduino/
*/
#ifndef SI443X_H_
#define SI443X_H_
#include <stdint.h>
//#include "Si446x_config.h"
// Address matching doesnt really work very well as the FIFO still needs to be
// manually cleared after receiving a packet, so the MCU still needs to wakeup and
// do stuff instead of the radio doing things automatically :/
#define SI446X_MAX_PACKET_LEN 128 ///< Maximum packet length
#define SI446X_MAX_TX_POWER 127 ///< Maximum TX power (+20dBm/100mW)
#define SI446X_WUT_RUN 1 ///< Wake the microcontroller when the WUT expires
#define SI446X_WUT_BATT 2 ///< Take a battery measurement when the WUT expires
#define SI446X_WUT_RX 4 ///< Go into RX mode for LDC time (not supported yet!)
#define SI446X_GPIO_PULL_EN 0x40 ///< Pullup enable for GPIO pins
#define SI446X_GPIO_PULL_DIS 0x00 ///< Pullup disable for GPIO pins
#define SI446X_NIRQ_PULL_EN 0x40 ///< Pullup enable for NIRQ pin
#define SI446X_NIRQ_PULL_DIS 0x00 ///< Pullup disable for NIRQ pin
#define SI446X_SDO_PULL_EN 0x40 ///< Pullup enable for SDO pin
#define SI446X_SDO_PULL_DIS 0x00 ///< Pullup disable for SDO pin
#define SI446X_PIN_PULL_EN 0x40 ///< Pullup enable for any pin
#define SI446X_PIN_PULL_DIS 0x00 ///< Pullup disable for any pin
#define SI446X_GPIO_DRV_HIGH 0x00 ///< GPIO drive strength high
#define SI446X_GPIO_DRV_MED_HIGH 0x20 ///< GPIO drive strength medium-high
#define SI446X_GPIO_DRV_MED_LOW 0x40 ///< GPIO drive strength medium-low
#define SI446X_GPIO_DRV_LOW 0x60 ///< GPIO drive strength low
#define SI446X_PROP_GROUP_GLOBAL 0x00 ///< Property group global
#define SI446X_PROP_GROUP_INT 0x01 ///< Property group interrupts
#define SI446X_PROP_GROUP_FRR 0x02 ///< Property group fast response registers
#define SI446X_PROP_GROUP_PREAMBLE 0x10 ///< Property group preamble
#define SI446X_PROP_GROUP_SYNC 0x11 ///< Property group sync
#define SI446X_PROP_GROUP_PKT 0x12 ///< Property group packet config
#define SI446X_PROP_GROUP_MODEM 0x20 ///< Property group modem
#define SI446X_PROP_GROUP_MODEM_CHFLT 0x21 ///< Property group RX coefficients
#define SI446X_PROP_GROUP_PA 0x22 ///< Property group power amp
#define SI446X_PROP_GROUP_SYNTH 0x23 ///< Property group synthesizer
#define SI446X_PROP_GROUP_MATCH 0x30 ///< Property group address match
#define SI446X_PROP_GROUP_FREQ_CONTROL 0x40 ///< Property group frequency control
#define SI446X_PROP_GROUP_RX_HOP 0x50 ///< Property group RX hop
#define SI446X_PROP_GROUP_PTI 0xF0 ///< Property group packet trace interface
/**
* @brief GPIO pin modes (see the Si446x API docs for what they all mean)
*/
typedef enum
{
SI446X_GPIO_MODE_DONOTHING = 0x00,
SI446X_GPIO_MODE_TRISTATE = 0x01,
SI446X_GPIO_MODE_DRIVE0 = 0x02,
SI446X_GPIO_MODE_DRIVE1 = 0x03,
SI446X_GPIO_MODE_INPUT = 0x04,
SI446X_GPIO_MODE_32K_CLK = 0x05,
SI446X_GPIO_MODE_BOOT_CLK = 0x06,
SI446X_GPIO_MODE_DIV_CLK = 0x07,
SI446X_GPIO_MODE_CTS = 0x08,
SI446X_GPIO_MODE_INV_CTS = 0x09,
SI446X_GPIO_MODE_CMD_OVERLAP = 0x0A,
SI446X_GPIO_MODE_SDO = 0x0B,
SI446X_GPIO_MODE_POR = 0x0C,
SI446X_GPIO_MODE_CAL_WUT = 0x0D,
SI446X_GPIO_MODE_WUT = 0x0E,
SI446X_GPIO_MODE_EN_PA = 0x0F,
SI446X_GPIO_MODE_TX_DATA_CLK = 0x10,
SI446X_GPIO_MODE_RX_DATA_CLK = 0x11,
SI446X_GPIO_MODE_EN_LNA = 0x12,
SI446X_GPIO_MODE_TX_DATA = 0x13,
SI446X_GPIO_MODE_RX_DATA = 0x14,
SI446X_GPIO_MODE_RX_RAW_DATA = 0x15,
SI446X_GPIO_MODE_ANTENNA_1_SW = 0x16,
SI446X_GPIO_MODE_ANTENNA_2_SW = 0x17,
SI446X_GPIO_MODE_VALID_PREAMBLE = 0x18,
SI446X_GPIO_MODE_INVALID_PREAMBLE = 0x19,
SI446X_GPIO_MODE_SYNC_WORD_DETECT = 0x1A,
SI446X_GPIO_MODE_CCA = 0x1B,
SI446X_GPIO_MODE_IN_SLEEP = 0x1C,
SI446X_GPIO_MODE_PKT_TRACE = 0x1D,
// Nothing for 0x1E (30)
SI446X_GPIO_MODE_TX_RX_DATA_CLK = 0x1F,
SI446X_GPIO_MODE_TX_STATE = 0x20,
SI446X_GPIO_MODE_RX_STATE = 0x21,
SI446X_GPIO_MODE_RX_FIFO_FULL = 0x22,
SI446X_GPIO_MODE_TX_FIFO_EMPTY = 0x23,
SI446X_GPIO_MODE_LOW_BATT = 0x24,
SI446X_GPIO_MODE_CCA_LATCH = 0x25,
SI446X_GPIO_MODE_HOPPED = 0x26,
SI446X_GPIO_MODE_HOP_TABLE_WRAP = 0x27
} si446x_gpio_mode_t;
/**
* @brief NIRQ pin modes (see the Si446x API docs for what they all mean)
*/
typedef enum
{
SI446X_NIRQ_MODE_DONOTHING = 0x00,
SI446X_NIRQ_MODE_TRISTATE = 0x01,
SI446X_NIRQ_MODE_DRIVE0 = 0x02,
SI446X_NIRQ_MODE_DRIVE1 = 0x03,
SI446X_NIRQ_MODE_INPUT = 0x04,
// SI446X_NIRQ_MODE_32K_CLK = 0x05,
// SI446X_NIRQ_MODE_BOOT_CLK = 0x06,
SI446X_NIRQ_MODE_DIV_CLK = 0x07,
SI446X_NIRQ_MODE_CTS = 0x08,
// SI446X_NIRQ_MODE_INV_CTS = 0x09,
// SI446X_NIRQ_MODE_CMD_OVERLAP = 0x0A,
SI446X_NIRQ_MODE_SDO = 0x0B,
SI446X_NIRQ_MODE_POR = 0x0C,
// SI446X_NIRQ_MODE_CAL_WUT = 0x0D,
// SI446X_NIRQ_MODE_WUT = 0x0E,
SI446X_NIRQ_MODE_EN_PA = 0x0F,
SI446X_NIRQ_MODE_TX_DATA_CLK = 0x10,
SI446X_NIRQ_MODE_RX_DATA_CLK = 0x11,
SI446X_NIRQ_MODE_EN_LNA = 0x12,
SI446X_NIRQ_MODE_TX_DATA = 0x13,
SI446X_NIRQ_MODE_RX_DATA = 0x14,
SI446X_NIRQ_MODE_RX_RAW_DATA = 0x15,
SI446X_NIRQ_MODE_ANTENNA_1_SW = 0x16,
SI446X_NIRQ_MODE_ANTENNA_2_SW = 0x17,
SI446X_NIRQ_MODE_VALID_PREAMBLE = 0x18,
SI446X_NIRQ_MODE_INVALID_PREAMBLE = 0x19,
SI446X_NIRQ_MODE_SYNC_WORD_DETECT = 0x1A,
SI446X_NIRQ_MODE_CCA = 0x1B,
// SI446X_NIRQ_MODE_IN_SLEEP = 0x1C,
SI446X_NIRQ_MODE_PKT_TRACE = 0x1D,
// Nothing for 0x1E (30)
SI446X_NIRQ_MODE_TX_RX_DATA_CLK = 0x1F,
// SI446X_NIRQ_MODE_TX_STATE = 0x20,
// SI446X_NIRQ_MODE_RX_STATE = 0x21,
// SI446X_NIRQ_MODE_RX_FIFO_FULL = 0x22,
// SI446X_NIRQ_MODE_TX_FIFO_EMPTY = 0x23,
// SI446X_NIRQ_MODE_LOW_BATT = 0x24,
// SI446X_NIRQ_MODE_CCA_LATCH = 0x25,
// SI446X_NIRQ_MODE_HOPPED = 0x26,
SI446X_NIRQ_MODE_NIRQ = 0x27
} si446x_nirq_mode_t;
/**
* @brief SDO pin modes (see the Si446x API docs for what they all mean)
*/
typedef enum
{
SI446X_SDO_MODE_DONOTHING = 0x00,
SI446X_SDO_MODE_TRISTATE = 0x01,
SI446X_SDO_MODE_DRIVE0 = 0x02,
SI446X_SDO_MODE_DRIVE1 = 0x03,
SI446X_SDO_MODE_INPUT = 0x04,
SI446X_SDO_MODE_32K_CLK = 0x05,
// SI446X_SDO_MODE_BOOT_CLK = 0x06,
SI446X_SDO_MODE_DIV_CLK = 0x07,
SI446X_SDO_MODE_CTS = 0x08,
// SI446X_SDO_MODE_INV_CTS = 0x09,
// SI446X_SDO_MODE_CMD_OVERLAP = 0x0A,
SI446X_SDO_MODE_SDO = 0x0B,
SI446X_SDO_MODE_POR = 0x0C,
// SI446X_SDO_MODE_CAL_WUT = 0x0D,
SI446X_SDO_MODE_WUT = 0x0E,
SI446X_SDO_MODE_EN_PA = 0x0F,
SI446X_SDO_MODE_TX_DATA_CLK = 0x10,
SI446X_SDO_MODE_RX_DATA_CLK = 0x11,
SI446X_SDO_MODE_EN_LNA = 0x12,
SI446X_SDO_MODE_TX_DATA = 0x13,
SI446X_SDO_MODE_RX_DATA = 0x14,
SI446X_SDO_MODE_RX_RAW_DATA = 0x15,
SI446X_SDO_MODE_ANTENNA_1_SW = 0x16,
SI446X_SDO_MODE_ANTENNA_2_SW = 0x17,
SI446X_SDO_MODE_VALID_PREAMBLE = 0x18,
SI446X_SDO_MODE_INVALID_PREAMBLE = 0x19,
SI446X_SDO_MODE_SYNC_WORD_DETECT = 0x1A,
SI446X_SDO_MODE_CCA = 0x1B,
// SI446X_SDO_MODE_IN_SLEEP = 0x1C,
// SI446X_SDO_MODE_PKT_TRACE = 0x1D,
// Nothing for 0x1E (30)
// SI446X_SDO_MODE_TX_RX_DATA_CLK = 0x1F,
// SI446X_SDO_MODE_TX_STATE = 0x20,
// SI446X_SDO_MODE_RX_STATE = 0x21,
// SI446X_SDO_MODE_RX_FIFO_FULL = 0x22,
// SI446X_SDO_MODE_TX_FIFO_EMPTY = 0x23,
// SI446X_SDO_MODE_LOW_BATT = 0x24,
// SI446X_SDO_MODE_CCA_LATCH = 0x25,
// SI446X_SDO_MODE_HOPPED = 0x26,
// SI446X_SDO_MODE_HOP_TABLE_WRAP = 0x27
} si446x_sdo_mode_t;
/**
* @brief Data structure for storing chip info from ::Si446x_getInfo()
*/
typedef struct {
uint8_t chipRev; ///< Chip revision
uint16_t part; ///< Part ID
uint8_t partBuild; ///< Part build
uint16_t id; ///< ID
uint8_t customer; ///< Customer
uint8_t romId; ///< ROM ID (3 = revB1B, 6 = revC2A)
uint8_t revExternal; ///< Revision external
uint8_t revBranch; ///< Revision branch
uint8_t revInternal; ///< Revision internal
uint16_t patch; ///< Patch
uint8_t func; ///< Function
} si446x_info_t;
/**
* @brief GPIOs for passing to ::Si446x_writeGPIO(), or for masking when reading from ::Si446x_readGPIO()
*/
typedef enum
{
SI446X_GPIO0 = 0, ///< GPIO 1
SI446X_GPIO1 = 1, ///< GPIO 2
SI446X_GPIO2 = 2, ///< GPIO 3
SI446X_GPIO3 = 3, ///< GPIO 4
SI446X_NIRQ = 4, ///< NIRQ
SI446X_SDO = 5 ///< SDO
} si446x_gpio_t;
/**
* @brief Radio states, returned from ::Si446x_getState()
*/
typedef enum
{
SI446X_STATE_NOCHANGE = 0x00,
SI446X_STATE_SLEEP = 0x01, ///< This will never be returned since SPI activity will wake the radio into ::SI446X_STATE_SPI_ACTIVE
SI446X_STATE_SPI_ACTIVE = 0x02,
SI446X_STATE_READY = 0x03,
SI446X_STATE_READY2 = 0x04, ///< Will return as ::SI446X_STATE_READY
SI446X_STATE_TX_TUNE = 0x05, ///< Will return as ::SI446X_STATE_TX
SI446X_STATE_RX_TUNE = 0x06, ///< Will return as ::SI446X_STATE_RX
SI446X_STATE_TX = 0x07,
SI446X_STATE_RX = 0x08
} si446x_state_t;
#define SI446X_CBS_SENT _BV(5+8) ///< Enable/disable packet sent callback
//#define SI446X_CBS_RXCOMPLETE _BV(4+8)
//#define SI446X_CBS_RXINVALID _BV(3+8)
#define SI446X_CBS_RXBEGIN _BV(0) ///< Enable/disable packet receive begin callback
//#define SI446X_CBS_INVALIDSYNC _BV(5) ///< Don't use this, it's used internally by the library
/**
* @brief Initialise, must be called before anything else!
*
* @return (none)
*/
void Si446x_init(void);
/**
* @brief Get chip info, see ::si446x_info_t
*
* @see ::si446x_info_t
* @param [info] Pointer to allocated ::si446x_info_t struct to place data into
* @return (none)
*/
void Si446x_getInfo(si446x_info_t* info);
/**
* @brief Get the current RSSI, the chip needs to be in receive mode for this to work
*
* @return The current RSSI in dBm (usually between -130 and 0)
*/
int16_t Si446x_getRSSI(void);
/**
* @brief Set the transmit power. The output power does not follow the \p pwr value, see the Si446x datasheet for a pretty graph
*
* 0 = -32dBm (<1uW)\n
* 7 = 0dBm (1mW)\n
* 12 = 5dBm (3.2mW)\n
* 22 = 10dBm (10mW)\n
* 40 = 15dBm (32mW)\n
* 100 = 20dBm (100mW)
*
* @param [pwr] A value from 0 to 127
* @return (none)
*/
void Si446x_setTxPower(uint8_t pwr);
/**
* @brief Enable or disable callbacks. This is mainly to configure what events should wake the microcontroller up.
*
* @param [callbacks] The callbacks to configure (multiple callbacks should be bitewise OR'd together)
* @param [state] Enable or disable the callbacks passed in \p callbacks parameter (1 = Enable, 0 = Disable)
* @return (none)
*/
void Si446x_setupCallback(uint16_t callbacks, uint8_t state);
/**
* @brief Read received data from FIFO
*
* @param [buff] Pointer to buffer to place data
* @param [len] Number of bytes to read, make sure not to read more bytes than what the FIFO has stored. The number of bytes that can be read is passed in the ::SI446X_CB_RXCOMPLETE() callback.
* @return (none)
*/
void Si446x_read(void* buff, uint8_t len);
/**
* @brief Transmit a packet
*
* @param [packet] Pointer to packet data
* @param [len] Number of bytes to transmit, maximum of ::SI446X_MAX_PACKET_LEN If configured for fixed length packets then this parameter is ignored and the length is set by ::SI446X_FIXED_LENGTH in Si446x_config.h
* @param [channel] Channel to transmit data on (0 - 255)
* @param [onTxFinish] What state to enter when the packet has finished transmitting. Usually ::SI446X_STATE_SLEEP or ::SI446X_STATE_RX
* @return 0 on failure (already transmitting), 1 on success (has begun transmitting)
*/
uint8_t Si446x_TX(void* packet, uint8_t len, uint8_t channel, si446x_state_t onTxFinish);
/**
* @brief Enter receive mode
*
* Entering RX mode will abort any transmissions happening at the time
*
* @param [channel] Channel to listen to (0 - 255)
* @return (none)
*/
void Si446x_RX(uint8_t channel);
/*-*
* @brief Changes will be applied next time the radio enters RX mode (NOT SUPPORTED)
*
* @param [mode] TODO
* @param [address] TODO
* @return (none)
*/
//void Si446x_setAddress(si446x_addrMode_t mode, uint8_t address);
/**
* @brief Set the low battery voltage alarm
*
* The ::SI446X_CB_LOWBATT() callback will be ran when the supply voltage drops below this value. The WUT must be configured with ::Si446x_setupWUT() to enable periodically checking the battery level.
*
* @param [voltage] The low battery threshold in millivolts (1050 - 3050).
* @return (none)
*/
void Si446x_setLowBatt(uint16_t voltage);
/**
* @brief Configure the wake up timer
*
* This function will also reset the timer.\n
*\n
* The Wake Up Timer (WUT) can be used to periodically run a number of features:\n
* ::SI446X_WUT_RUN Simply wake up the microcontroller when the WUT expires and run the ::SI446X_CB_WUT() callback.\n
* ::SI446X_WUT_BATT Check battery voltage - If the battery voltage is below the threshold set by ::Si446x_setLowBatt() then wake up the microcontroller and run the ::SI446X_CB_LOWBATT() callback.\n
* ::SI446X_WUT_RX Enter receive mode for a length of time determinded by the ldc and r parameters (NOT SUPPORTED YET! dont use this option)\n
*\n
* For more info see the GLOBAL_WUT_M, GLOBAL_WUT_R and GLOBAL_WUT_LDC properties in the Si446x API docs.\n
*
* @note When first turning on the WUT this function will take around 300us to complete
* @param [r] Exponent value for WUT and LDC (Maximum valus is 20)
* @param [m] Mantissia value for WUT
* @param [ldc] Mantissia value for LDC (NOT SUPPORTED YET, just pass 0 for now)
* @param [config] Which WUT features to enable ::SI446X_WUT_RUN ::SI446X_WUT_BATT ::SI446X_WUT_RX These can be bitwise OR'ed together to enable multiple features.
* @return (none)
*/
void Si446x_setupWUT(uint8_t r, uint16_t m, uint8_t ldc, uint8_t config);
/**
* @brief Disable the wake up timer
*
* @return (none)
*/
void Si446x_disableWUT(void);
/**
* @brief Enter sleep mode
*
* If WUT is enabled then the radio will keep the internal 32KHz RC enabled with a current consumption of 740nA, otherwise the current consumption will be 40nA without WUT.
* Sleep will fail if the radio is currently transmitting.
*
* @note Any SPI communications with the radio will wake the radio into ::SI446X_STATE_SPI_ACTIVE mode. ::Si446x_sleep() will need to called again to put it back into sleep mode.
*
* @return 0 on failure (busy transmitting something), 1 on success
*/
uint8_t Si446x_sleep(void);
/**
* @brief Get the radio status
*
* @see ::si446x_state_t
* @return The current radio status
*/
si446x_state_t Si446x_getState(void);
/**
* @brief Read pin ADC value
*
* @param [pin] The GPIO pin number (0 - 3)
* @return ADC value (0 - 2048, where 2048 is 3.6V)
*/
uint16_t Si446x_adc_gpio(uint8_t pin);
/**
* @brief Read supply voltage
*
* @return Supply voltage in millivolts
*/
uint16_t Si446x_adc_battery(void);
/**
* @brief Read temperature
*
* @return Temperature in C
*/
float Si446x_adc_temperature(void);
/**
* @brief Configure GPIO/NIRQ/SDO pin
*
* @note NIRQ and SDO pins should not be changed, unless you really know what you're doing. 2 of the GPIO pins (usually 0 and 1) are also usually used for the RX/TX RF switch and should also be left alone.
*
* @param [pin] The pin, this can only take a single pin (don't use bitwise OR), see ::si446x_gpio_t
* @param [value] The new pin mode, this can be bitwise OR'd with the ::SI446X_PIN_PULL_EN option, see ::si446x_gpio_mode_t ::si446x_nirq_mode_t ::si446x_sdo_mode_t
* @return (none)
*/
void Si446x_writeGPIO(si446x_gpio_t pin, uint8_t value);
/**
* @brief Read GPIO pin states
*
* @return The pin states. Use ::si446x_gpio_t to mask the value to get the state for the desired pin.
*/
uint8_t Si446x_readGPIO(void);
/**
* @brief Get all values of a property group
*
* @param [buff] Pointer to memory to place group values, if this is NULL then nothing will be dumped, just the group size is returned
* @param [group] The group to dump
* @return Size of the property group
*/
uint8_t Si446x_dump(void* buff, uint8_t group);
#endif /* SI443X_H_ */

@ -0,0 +1,124 @@
/*
* Project: Si4463 Radio Library for AVR and Arduino
* Author: Zak Kemble, contact@zakkemble.co.uk
* Copyright: (C) 2017 by Zak Kemble
* License: GNU GPL v3 (see License.txt)
* Web: http://blog.zakkemble.co.uk/si4463-radio-library-avr-arduino/
*/
#ifndef SI446X_DEFS_H_
#define SI446X_DEFS_H_
#define SI446X_CMD_POWER_UP 0x02
#define SI446X_CMD_NOP 0x00
#define SI446X_CMD_PART_INFO 0x01
#define SI446X_CMD_FUNC_INFO 0x10
#define SI446X_CMD_SET_PROPERTY 0x11
#define SI446X_CMD_GET_PROPERTY 0x12
#define SI446X_CMD_GPIO_PIN_CFG 0x13
#define SI446X_CMD_FIFO_INFO 0x15
#define SI446X_CMD_GET_INT_STATUS 0x20
#define SI446X_CMD_REQUEST_DEVICE_STATE 0x33
#define SI446X_CMD_CHANGE_STATE 0x34
#define SI446X_CMD_READ_CMD_BUFF 0x44
#define SI446X_CMD_READ_FRR_A 0x50
#define SI446X_CMD_READ_FRR_B 0x51
#define SI446X_CMD_READ_FRR_C 0x53
#define SI446X_CMD_READ_FRR_D 0x57
#define SI446X_CMD_IRCAL 0x17
#define SI446X_CMD_IRCAL_MANUAL 0x1a
#define SI446X_CMD_START_TX 0x31
#define SI446X_CMD_TX_HOP 0x37
#define SI446X_CMD_WRITE_TX_FIFO 0x66
#define SI446X_CMD_PACKET_INFO 0x16
#define SI446X_CMD_GET_MODEM_STATUS 0x22
#define SI446X_CMD_START_RX 0x32
#define SI446X_CMD_RX_HOP 0x36
#define SI446X_CMD_READ_RX_FIFO 0x77
#define SI446X_CMD_GET_ADC_READING 0x14
#define SI446X_CMD_GET_PH_STATUS 0x21
#define SI446X_CMD_GET_CHIP_STATUS 0x23
#define SI446X_INT_CTL_CHIP_LOW_BATT_EN 1
#define SI446X_INT_CTL_CHIP_WUT_EN 0
typedef enum
{
SI446X_ADC_CONV_TEMP = 16,
SI446X_ADC_CONV_BATT = 8,
SI446X_ADC_CONV_GPIO = 4
} si446x_adc_conv_t;
typedef enum
{
SI446X_ADC_RANGE_0P8 = 0,
SI446X_ADC_RANGE_1P6 = 4,
SI446X_ADC_RANGE_3P2 = 5,
SI446X_ADC_RANGE_2P4 = 8,
SI446X_ADC_RANGE_3P6 = 9
} si446x_adc_range_t;
#define SI446X_FIFO_CLEAR_RX 0x02
#define SI446X_FIFO_CLEAR_TX 0x01
#define GLOBAL_PROP(prop) ((SI446X_PROP_GROUP_GLOBAL<<8) | prop)
#define INT_PROP(prop) ((SI446X_PROP_GROUP_INT<<8) | prop)
#define PKT_PROP(prop) ((SI446X_PROP_GROUP_PKT<<8) | prop)
#define PA_PROP(prop) ((SI446X_PROP_GROUP_PA<<8) | prop)
#define MATCH_PROP(prop) ((SI446X_PROP_GROUP_MATCH<<8) | prop)
#define SI446X_GLOBAL_CONFIG GLOBAL_PROP(0x03)
#define SI446X_FIFO_MODE_HALF_DUPLEX 0x10
#define SI446X_GLOBAL_CLK_CFG GLOBAL_PROP(0x01)
#define SI446X_DIVIDED_CLK_DIS 0x00
#define SI446X_DIVIDED_CLK_EN 0x40
#define SI446X_DIVIDED_CLK_SEL_DIV_1 0<<5
#define SI446X_DIVIDED_CLK_SEL_DIV_2 1<<5
#define SI446X_DIVIDED_CLK_SEL_DIV_3 2<<5
#define SI446X_DIVIDED_CLK_SEL_DIV_7_5 3<<5
#define SI446X_DIVIDED_CLK_SEL_DIV_10 4<<5
#define SI446X_DIVIDED_CLK_SEL_DIV_15 5<<5
#define SI446X_DIVIDED_CLK_SEL_DIV_30 6<<5
#define SI446X_DIVIDED_CLK_32K_SEL_OFF 0x00
#define SI446X_DIVIDED_CLK_32K_SEL_RC 0x01
#define SI446X_DIVIDED_CLK_32K_SEL_XTAL 0x02
#define SI446X_GLOBAL_LOW_BATT_THRESH GLOBAL_PROP(0x02)
#define SI446X_GLOBAL_WUT_CONFIG GLOBAL_PROP(0x04)
#define SI446X_GLOBAL_WUT_M GLOBAL_PROP(0x05)
#define SI446X_GLOBAL_WUT_R GLOBAL_PROP(0x07)
#define SI446X_GLOBAL_WUT_LDC GLOBAL_PROP(0x08)
#define SI446X_WUT_SLEEP 5
#define SI446X_LDC_MAX_PERIODS_FOREVER 0<<6
#define SI446X_LDC_MAX_PERIODS_TWO 1<<6
#define SI446X_LDC_MAX_PERIODS_FOUR 2<<6
#define SI446X_LDC_MAX_PERIODS_EIGHT 3<<6
#define SI446X_GLOBAL_WUT_CONFIG_WUT_LDC_EN_RX 1<<6
#define SI446X_GLOBAL_WUT_CONFIG_WUT_EN 1
#define SI446X_GLOBAL_WUT_CONFIG_WUT_LBD_EN 2
#define SI446X_INT_CTL_ENABLE INT_PROP(0x00)
#define SI446X_INT_CTL_PH_ENABLE INT_PROP(0x01)
#define SI446X_INT_CTL_MODEM_ENABLE INT_PROP(0x02)
#define SI446X_INT_CTL_CHIP_ENABLE INT_PROP(0x03)
#define SI446X_FILTER_MATCH_PEND 7
#define SI446X_FILTER_MISS_PEND 6
#define SI446X_PACKET_SENT_PEND 5
#define SI446X_PACKET_RX_PEND 4
#define SI446X_CRC_ERROR_PEND 3
#define SI446X_INVALID_SYNC_PEND 5
#define SI446X_SYNC_DETECT_PEND 0
#define SI446X_LOW_BATT_PEND 1
#define SI446X_WUT_PEND 0
#define SI446X_MATCH_VALUE_1 MATCH_PROP(0x00)
#define SI446X_MATCH_EN 0x40
#define SI446X_PA_PWR_LVL PA_PROP(0x01)
#define SI446X_PKT_FIELD_1_LENGTH PKT_PROP(0x0D)
#define SI446X_PKT_FIELD_2_LENGTH PKT_PROP(0x11)
#define SI446X_PKT_FIELD_2_LENGTH_LOW PKT_PROP(0x12)
#endif /* SI446X_DEFS_H_ */

@ -2741,6 +2741,9 @@ goto again;
i2sObjectInit(&I2SD2);
i2sStart(&I2SD2, &i2sconfig);
i2sStartExchange(&I2SD2);
#endif
#ifdef __SI4463__
SI4463_init();
#endif
area_height = AREA_HEIGHT_NORMAL;
ui_init();

@ -37,6 +37,7 @@
//#define __ULTRA__ // Add harmonics mode on low input.
//#define __ULTRA_SA__ // Adds ADF4351 control for extra high 1st IF stage
#define __SPUR__ // Does spur reduction by shifting IF
#define __SI4463__
/*
* main.c

@ -1710,8 +1710,8 @@ pureRSSI_t perform(bool break_on_operation, int i, uint32_t f, int tracking)
start_of_sweep_timestamp = chVTGetSystemTimeX();
}
else
pureRSSI = SI4432_RSSI(lf, MODE_SELECT(setting.mode)); // Get RSSI, either from pre-filled buffer
// pureRSSI = SI4432_RSSI(lf, MODE_SELECT(setting.mode)); // Get RSSI, either from pre-filled buffer
pureRSSI = Si446x_RSSI(); // Get RSSI, either from pre-filled buffer
#ifdef __SPUR__
static pureRSSI_t spur_RSSI = -1; // Initialization only to avoid warning.
if (setting.spur == 1) { // If first spur pass

@ -26,7 +26,7 @@
#include "spi.h"
#pragma GCC push_options
#pragma GCC optimize ("O2")
#pragma GCC optimize ("Og")
// Define for use hardware SPI mode
#define USE_HARDWARE_SPI_MODE
@ -38,12 +38,15 @@
#define SI_CS_LOW palClearPad(GPIOA, GPIOA_SI_SEL)
#define SI_CS_HIGH palSetPad(GPIOA, GPIOA_SI_SEL)
#define SI_SDN_LOW palClearPad(GPIOC, 15)
#define SI_SDN_HIGH palSetPad(GPIOC, 15)
// Hardware or software SPI use
#ifdef USE_HARDWARE_SPI_MODE
#define SI4432_SPI SPI1
//#define SI4432_SPI_SPEED SPI_BR_DIV8
#define SI4432_SPI_SPEED SPI_BR_DIV64
#define SI4432_SPI_SPEED SPI_BR_DIV32
static uint32_t old_spi_settings;
#else
static uint32_t old_port_moder;
@ -201,7 +204,7 @@ static void shiftOutBuf(uint8_t *buf, uint16_t size) {
}
#endif
const uint16_t SI_nSEL[MAX_SI4432+1] = { GPIOB_RX_SEL, GPIOB_LO_SEL, 0}; // #3 is dummy!!!!!!
const uint16_t SI_nSEL[MAX_SI4432+1] = { GPIOB_LO_SEL, GPIOB_LO_SEL, 0}; // #3 is dummy!!!!!!
volatile int SI4432_Sel = 0; // currently selected SI4432
// volatile int SI4432_guard = 0;
@ -676,6 +679,7 @@ void SI4432_Sub_Init(void)
void SI4432_Init()
{
return;
#if 1
CS_SI0_LOW; // Drop CS so power can be removed
@ -1200,4 +1204,332 @@ void ADF4351_prep_frequency(int channel, unsigned long freq, int drive) // freq
#endif
// ------------------------------ SI4463 -------------------------------------
#include <string.h>
void SI4463_write_byte(byte ADR, byte DATA)
{
set_SPI_mode(SPI_MODE_SI);
// if (SI4432_guard)
// while(1) ;
// SI4432_guard = 1;
// SPI1_CLK_LOW;
palClearPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
// chThdSleepMicroseconds(SELECT_DELAY);
ADR |= 0x80 ; // RW = 1
shiftOut( ADR );
shiftOut( DATA );
my_microsecond_delay(2);
palSetPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
// SI4432_guard = 0;
}
void SI4463_write_buffer(byte ADR, byte *DATA, int len)
{
set_SPI_mode(SPI_MODE_SI);
// if (SI4432_guard)
// while(1) ;
// SI4432_guard = 1;
// SPI1_CLK_LOW;
palClearPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
// chThdSleepMicroseconds(SELECT_DELAY);
ADR |= 0x80 ; // RW = 1
shiftOut( ADR );
while (len-- > 0)
shiftOut( *(DATA++) );
my_microsecond_delay(2);
palSetPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
// SI4432_guard = 0;
}
byte SI4463_read_byte( byte ADR )
{
// set_SPI_mode(SPI_MODE_SI);
byte DATA ;
// if (SI4432_guard)
// while(1) ;
// SI4432_guard = 1;
// SPI1_CLK_LOW;
palClearPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
shiftOut( ADR );
my_microsecond_delay(2);
DATA = shiftIn();
my_microsecond_delay(2);
palSetPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
// SI4432_guard = 0;
return DATA ;
}
uint8_t SI4463_get_response(void* buff, uint8_t len)
{
uint8_t cts = 0;
set_SPI_mode(SPI_MODE_SI);
// if (SI4432_guard)
// while(1) ;
// SI4432_guard = 1;
// SPI1_CLK_LOW;
palClearPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
shiftOut( SI446X_CMD_READ_CMD_BUFF );
my_microsecond_delay(2);
cts = (shiftIn() == 0xFF);
my_microsecond_delay(2);
if (cts)
{
// Get response data
for(uint8_t i=0;i<len;i++) {
((uint8_t*)buff)[i] = shiftIn();
my_microsecond_delay(2);
}
}
palSetPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
return cts;
}
uint8_t SI4463_wait_response(void* buff, uint8_t len, uint8_t use_timeout)
{
uint16_t timeout = 40000;
while(!SI4463_get_response(buff, len))
{
my_microsecond_delay(5);
if(use_timeout && !--timeout)
{
return 0;
}
}
return 1;
}
void SI4463_do_api(void* data, uint8_t len, void* out, uint8_t outLen)
{
if(SI4463_wait_response(NULL, 0, true)) // Make sure it's ok to send a command
{
// set_SPI_mode(SPI_MODE_SI);
palClearPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
for(uint8_t i=0;i<len;i++) {
shiftOut(((uint8_t*)data)[i]); // (pgm_read_byte(&((uint8_t*)data)[i]));
my_microsecond_delay(2);
}
my_microsecond_delay(2);
palSetPad(GPIOB, GPIOB_RX_SEL);
my_microsecond_delay(2);
if(((uint8_t*)data)[0] == SI446X_CMD_IRCAL) // If we're doing an IRCAL then wait for its completion without a timeout since it can sometimes take a few seconds
SI4463_wait_response(NULL, 0, false);
else if(out != NULL) // If we have an output buffer then read command response into it
SI4463_wait_response(out, outLen, true);
}
}
static void SI4463_set_properties(uint16_t prop, void* values, uint8_t len)
{
// len must not be greater than 12
uint8_t data[16] = {
SI446X_CMD_SET_PROPERTY,
(uint8_t)(prop>>8),
len,
(uint8_t)prop
};
// Copy values into data, starting at index 4
memcpy(data + 4, values, len);
SI4463_do_api(data, len + 4, NULL, 0);
}
#include "SI4463_radio_config.h"
#include "SI446x_cmd.h"
static const uint8_t SI4463_config[] = RADIO_CONFIGURATION_DATA_ARRAY;
// Set new state
static void SI4463_set_state(si446x_state_t newState)
{
uint8_t data[] = {
SI446X_CMD_CHANGE_STATE,
newState
};
SI4463_do_api(data, sizeof(data), NULL, 0);
}
static void SI4463_clear_FIFO(void)
{
// 'static const' saves 20 bytes of flash here, but uses 2 bytes of RAM
static const uint8_t clearFifo[] = {
SI446X_CMD_FIFO_INFO,
SI446X_FIFO_CLEAR_RX | SI446X_FIFO_CLEAR_TX
};
SI4463_do_api((uint8_t*)clearFifo, sizeof(clearFifo), NULL, 0);
}
void SI4463_start_rx(uint8_t CHANNEL)
{
uint8_t data[] = {
SI446X_CMD_ID_START_RX,
CHANNEL,
0,
0,
0,
SI446X_CMD_START_RX_ARG_NEXT_STATE1_RXTIMEOUT_STATE_ENUM_NOCHANGE,
SI446X_CMD_START_RX_ARG_NEXT_STATE2_RXVALID_STATE_ENUM_RX,
SI446X_CMD_START_RX_ARG_NEXT_STATE3_RXINVALID_STATE_ENUM_RX
};
//retry:
SI4463_do_api(data, sizeof(data), NULL, 0);
#if 0
// my_microsecond_delay(15000);
// si446x_state_t s = getState();
if (s != SI446X_STATE_RX) {
my_microsecond_delay(10);
goto retry;
}
#endif
}
si446x_info_t SI4463_info;
void Si446x_getInfo(si446x_info_t* info)
{
uint8_t data[8] = {
SI446X_CMD_PART_INFO
};
SI4463_do_api(data, 1, data, 8);
info->chipRev = data[0];
info->part = (data[1]<<8) | data[2];
info->partBuild = data[3];
info->id = (data[4]<<8) | data[5];
info->customer = data[6];
info->romId = data[7];
data[0] = SI446X_CMD_FUNC_INFO;
SI4463_do_api(data, 1, data, 6);
info->revExternal = data[0];
info->revBranch = data[1];
info->revInternal = data[2];
info->patch = (data[3]<<8) | data[4];
info->func = data[5];
}
// Read a fast response register
uint8_t getFRR(uint8_t reg)
{
return SI4463_read_byte(reg);
}
// Get current radio state
si446x_state_t getState(void)
{
uint8_t state = getFRR(SI446X_CMD_READ_FRR_B);
if(state == SI446X_STATE_TX_TUNE)
state = SI446X_STATE_TX;
else if(state == SI446X_STATE_RX_TUNE)
state = SI446X_STATE_RX;
else if(state == SI446X_STATE_READY2)
state = SI446X_STATE_READY;
return (si446x_state_t)state;
}
// Set new state
void setState(si446x_state_t newState)
{
uint8_t data[] = {
SI446X_CMD_CHANGE_STATE,
newState
};
SI4463_do_api(data, sizeof(data), NULL, 0);
}
int16_t Si446x_RSSI(void)
{
// Si446x_getInfo(&SI4463_info);
// if (s != SI446X_STATE_RX)
// SI4463_start_rx(90);
// SI4463_start_rx(90);
uint8_t data[3] = {
SI446X_CMD_GET_MODEM_STATUS,
0xFF
};
// volatile si446x_state_t s = getState();
SI4463_do_api(data, 2, data, 3);
int16_t rssi = 16 * data[2];
return rssi;
}
// Do an ADC conversion
static uint16_t getADC(uint8_t adc_en, uint8_t adc_cfg, uint8_t part)
{
uint8_t data[6] = {
SI446X_CMD_GET_ADC_READING,
adc_en,
adc_cfg
};
SI4463_do_api(data, 3, data, 6);
return (data[part]<<8 | data[part + 1]);
}
void SI4463_init(void)
{
volatile int16_t RSSI;
reset:
SI_SDN_LOW;
my_microsecond_delay(1000);
SI_SDN_HIGH;
my_microsecond_delay(10000);
SI_SDN_LOW;
my_microsecond_delay(10000);
#if 1
for(uint16_t i=0;i<sizeof(SI4463_config);i++)
{
SI4463_do_api((void *)&SI4463_config[i+1], SI4463_config[i], NULL, 0);
i += SI4463_config[i];
my_microsecond_delay(100);
}
#endif
// SI4463_do_api((void *)&SI4463_config[1], SI4463_config[0], NULL, 0);
//#define SI446X_ADC_SPEED 10
// RSSI = getADC(SI446X_ADC_CONV_BATT, (SI446X_ADC_SPEED<<4), 2);
volatile si446x_state_t s ;
again:
Si446x_getInfo(&SI4463_info);
// s = getState();
SI4463_start_rx(90);
my_microsecond_delay(15000);
s = getState();
if (s != SI446X_STATE_RX)
goto reset;
RSSI = Si446x_RSSI();
// goto again;
}
#pragma GCC pop_options

@ -160,5 +160,17 @@ void ADF4351_level(int p);
int ADF4351_locked(void);
#endif
#ifdef __SI4463__
#include "si446x_defs.h"
#include "si446x.h"
int16_t Si446x_RSSI(void);
uint8_t getFRR(uint8_t reg);
si446x_state_t getState(void);
void setState(si446x_state_t newState);
extern si446x_info_t SI4463_info;
void Si446x_getInfo(si446x_info_t* info);
void SI4463_init(void);
#endif
#endif //__SI4432_H__

File diff suppressed because it is too large Load Diff

@ -0,0 +1,80 @@
// COPYRIGHT=2015 Silicon Laboratories, Inc.
// GENERATED=09:13 October 20 2015
// ROMID=0x06
// FUNCTION=TEST
// MAJOR=0
// MINOR=0
// BUILD=0
// PATCHID=0xCA90
// REQUIRES=NONE
// SIZE=512
// CRCT=0x714b
#define SI446X_PATCH_ROMID 00
#define SI446X_PATCH_ID 00
#define SI446X_PATCH_CMDS \
0x08,0x04,0x21,0x71,0x4B,0x00,0x00,0xDC,0x95, \
0x08,0x05,0xA6,0x22,0x21,0xF0,0x41,0x5B,0x26, \
0x08,0xE2,0x2F,0x1C,0xBB,0x0A,0xA8,0x94,0x28, \
0x08,0x05,0x87,0x67,0xE2,0x58,0x1A,0x07,0x5B, \
0x08,0xE1,0xD0,0x72,0xD8,0x8A,0xB8,0x5B,0x7D, \
0x08,0x05,0x11,0xEC,0x9E,0x28,0x23,0x1B,0x6D, \
0x08,0xE2,0x4F,0x8A,0xB2,0xA9,0x29,0x14,0x13, \
0x08,0x05,0xD1,0x2E,0x71,0x6A,0x51,0x4C,0x2C, \
0x08,0xE5,0x80,0x27,0x42,0xA4,0x69,0xB0,0x7F, \
0x08,0x05,0xAA,0x81,0x2A,0xBD,0x45,0xE8,0xA8, \
0x08,0xEA,0xE4,0xF0,0x24,0xC9,0x9F,0xCC,0x3C, \
0x08,0x05,0x08,0xF5,0x05,0x04,0x27,0x62,0x98, \
0x08,0xEA,0x6B,0x62,0x84,0xA1,0xF9,0x4A,0xE2, \
0x08,0x05,0xE9,0x77,0x05,0x4F,0x84,0xEE,0x35, \
0x08,0xE2,0x43,0xC3,0x8D,0xFB,0xAD,0x54,0x25, \
0x08,0x05,0x14,0x06,0x5E,0x39,0x36,0x2F,0x45, \
0x08,0xEA,0x0C,0x1C,0x74,0xD0,0x11,0xFC,0x32, \
0x08,0x05,0xDA,0x38,0xBA,0x0E,0x3C,0xE7,0x8B, \
0x08,0xEA,0xB0,0x09,0xE6,0xFF,0x94,0xBB,0xA9, \
0x08,0x05,0xD7,0x11,0x29,0xFE,0xDC,0x71,0xD5, \
0x08,0xEA,0x7F,0x83,0xA7,0x60,0x90,0x62,0x18, \
0x08,0x05,0x84,0x7F,0x6A,0xD1,0x91,0xC6,0x52, \
0x08,0xEA,0x2A,0xD8,0x7B,0x8E,0x4A,0x9F,0x91, \
0x08,0x05,0xBD,0xAA,0x9D,0x16,0x18,0x06,0x15, \
0x08,0xE2,0x55,0xAD,0x2D,0x0A,0x14,0x1F,0x5D, \
0x08,0x05,0xD3,0xE0,0x7C,0x39,0xCF,0x01,0xF0, \
0x08,0xEF,0x3A,0x91,0x72,0x6A,0x03,0xBB,0x96, \
0x08,0xE7,0x83,0x6D,0xA4,0x92,0xFC,0x13,0xA7, \
0x08,0xEF,0xF8,0xFD,0xCF,0x62,0x07,0x6F,0x1E, \
0x08,0xE7,0x4C,0xEA,0x4A,0x75,0x4F,0xD6,0xCF, \
0x08,0xE2,0xF6,0x11,0xE4,0x26,0x0D,0x4D,0xC6, \
0x08,0x05,0xFB,0xBF,0xE8,0x07,0x89,0xC3,0x51, \
0x08,0xEF,0x82,0x27,0x04,0x3F,0x96,0xA8,0x58, \
0x08,0xE7,0x41,0x29,0x3C,0x75,0x2A,0x03,0x1C, \
0x08,0xEF,0xAF,0x59,0x98,0x36,0xAA,0x0F,0x06, \
0x08,0xE6,0xF6,0x93,0x41,0x2D,0xEC,0x0E,0x99, \
0x08,0x05,0x29,0x19,0x90,0xE5,0xAA,0x36,0x40, \
0x08,0xE7,0xFB,0x68,0x10,0x7D,0x77,0x5D,0xC0, \
0x08,0xE7,0xCB,0xB4,0xDD,0xCE,0x90,0x54,0xBE, \
0x08,0xE7,0x72,0x8A,0xD6,0x02,0xF4,0xDD,0xCC, \
0x08,0xE7,0x6A,0x21,0x0B,0x02,0x86,0xEC,0x15, \
0x08,0xE7,0x7B,0x7C,0x3D,0x6B,0x81,0x03,0xD0, \
0x08,0xEF,0x7D,0x61,0x36,0x94,0x7C,0xA0,0xDF, \
0x08,0xEF,0xCC,0x85,0x3B,0xDA,0xE0,0x5C,0x1C, \
0x08,0xE7,0xE3,0x75,0xBB,0x39,0x22,0x4B,0xA8, \
0x08,0xEF,0xF9,0xCE,0xE0,0x5E,0xEB,0x1D,0xCB, \
0x08,0xE7,0xBD,0xE2,0x70,0xD5,0xAB,0x4E,0x3F, \
0x08,0xE7,0xB7,0x8D,0x20,0x68,0x6B,0x09,0x52, \
0x08,0xEF,0xA1,0x1B,0x90,0xCD,0x98,0x00,0x63, \
0x08,0xEF,0x54,0x67,0x5D,0x9C,0x11,0xFC,0x45, \
0x08,0xE7,0xD4,0x9B,0xC8,0x97,0xBE,0x8A,0x07, \
0x08,0xEF,0x52,0x8D,0x90,0x63,0x73,0xD5,0x2A, \
0x08,0xEF,0x03,0xBC,0x6E,0x1C,0x76,0xBE,0x4A, \
0x08,0xE7,0xC2,0xED,0x67,0xBA,0x5E,0x66,0x21, \
0x08,0xEF,0xE7,0x3F,0x87,0xBE,0xE0,0x7A,0x6D, \
0x08,0xE7,0xC9,0x70,0x93,0x1D,0x64,0xF5,0x6C, \
0x08,0xEF,0xF5,0x28,0x08,0x34,0xB3,0xB6,0x2C, \
0x08,0xEF,0x3A,0x0A,0xEC,0x0F,0xDB,0x56,0xCA, \
0x08,0xEF,0x39,0xA0,0x6E,0xED,0x79,0xD0,0x24, \
0x08,0xE7,0x6C,0x0B,0xAF,0xA9,0x4E,0x40,0xB5, \
0x08,0xE9,0xB9,0xAF,0xBF,0x25,0x50,0xD1,0x37, \
0x08,0x05,0x9E,0xDB,0xDE,0x3F,0x94,0xE9,0x6B, \
0x08,0xEC,0xC5,0x05,0xAA,0x57,0xDC,0x8A,0x5E, \
0x08,0x05,0x70,0xDA,0x84,0x84,0xDD,0xCA,0x90
Loading…
Cancel
Save

Powered by TurnKey Linux.