123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161 |
- /*
- / _____) _ | |
- ( (____ _____ ____ _| |_ _____ ____| |__
- \____ \| ___ | (_ _) ___ |/ ___) _ \
- _____) ) ____| | | || |_| ____( (___| | | |
- (______/|_____)_|_|_| \__)_____)\____)_| |_|
- (C)2014 Semtech
- Description: sx1208 dirver
- License: Revised BSD License, see LICENSE.TXT file include in the project
- Maintainer: Leo Xie, Jiapeng Li
- */
- #include "myRadio_gpio.h"
- #include "sx1208-reg.h"
- #include "sx1208.h"
- #include "string.h"
- #include "sx1208-state-grid.h"
- #include "sx1231_params.h"
- #define SX1208_RX_FIFO_THRESH (66-15)
- #define SX1208_TX_FIFO_THRESH (15)
- #define SX1208_PAYLOAD_LENGTH_MAX (0xFF)
- uint8_t sx1208_read(uint8_t addr);
- void sx1208_write(uint8_t addr, uint8_t data);
- void sx1208_rmw(uint8_t addr, uint8_t mask, uint8_t val);
- void sx1208_rmw_bit(uint8_t addr, uint8_t bit, uint8_t val);
- void sx1208_read_burst(uint8_t addr, uint8_t *buf, uint16_t len);
- void sx1208_write_burst(uint8_t addr, uint8_t *buf, uint16_t len);
- int sx1208_read_fifo(uint8_t *buf, uint16_t len);
- int sx1208_write_fifo(uint8_t *buf, uint16_t len);
- // static void sx1208_set_rxbw(uint32_t fdev, uint32_t br);
- static void sx1208_set_preamble_reg(uint16_t len);
- static void sx1208_set_crc_auto_clear(sx1208_crc_auto_clear_t crcac_opt);
- void sx1208_irq_dio0(void);
- void sx1208_irq_dio1(void);
- void sx1208_irq_dio2(void);
- void sx1208_irq_dio3(void);
- void sx1208_irq_dio4(void);
- void sx1208_irq_dio5(void);
- volatile uint8_t sx1208_ext_fifo[256];
- volatile uint8_t sx1208_ext_fifo_rd_index;
- volatile uint8_t sx1208_ext_fifo_wr_index;
- volatile int16_t sx1208_ext_fifo_count;
- static volatile sx1208_callback_t sx1208_callback_g;
- static volatile uint16_t sx1208_tx_preamble_len_g;
- static volatile uint16_t sx1208_rx_preamble_len_g;
- static volatile uint8_t sx1208_high_power; // 0: off, 1: on
- static sx1208_rx_pkt_t sx1208_rx_pkt;
- static uint16_t sx1208_rx_payload_length;
- static sx1208_protocol_t sx1208_protocol;
- bool Irq0Fired = false;
- #define SX1208_FSK_RXBW_TAB_LENGTH (21)
- static const uint32_t sx1208_fsk_rxbw_tab[SX1208_FSK_RXBW_TAB_LENGTH]={
- 2600, 3100, 3900, 5200, 6300, 7800, 10400, 12500, 15600, 20800,
- 25000, 31300, 41700, 50000, 62500, 83300, 100000, 125000, 166700, 200000,
- 250000
- };
- static void delay_ms(uint32_t delay_ms)
- {
- uint32_t i = 0;
- uint32_t j = 0;
- for (i = 0; i < delay_ms; i++)
- {
- for (j = 0; j < 10000; j++)
- {
- ;
- }
- }
- }
- void sx1208_reset(void)
- {
- uint8_t i;
- // HAL_SX1208_RST_OUTPUT();
- RF_SX12xx_RST_H();
- delay_ms(1);
- // HAL_SX1208_RST_INPUT();
- RF_SX12xx_RST_L();
- delay_ms(6);
- }
- void sx1208_initParams(void)
- {
- uint8_t i;
- sx1208_params_unit_t *params;
- params = (sx1208_params_unit_t *)sx1231ParamsList;
- for ( i = 0; i < sizeof(sx1231ParamsList) / 2; i++)
- {
- if (params->addr != 0xff)
- {
- sx1208_write(params->addr, params->value);
- }
-
- params ++;
- }
-
- }
- void sx1208_init(sx1208_callback_t sx1208_cb)
- {
- uint8_t i;
- /** sfotware reset sx1208 */
- sx1208_reset();
- // sx1208_initParams();
- /** Callback function */
- sx1208_callback_g = NULL;
- if(sx1208_cb != NULL){
- sx1208_callback_g = sx1208_cb;
- }
- sx1208_ext_fifo_rd_index = 0;
- sx1208_ext_fifo_count = 0;
- sx1208_ext_fifo_wr_index = 0;
- sx1208_high_power = 0;
- sx1208_rx_pkt.buf = NULL;
- sx1208_rx_payload_length = 0;
- /** write default value to SX1208, refer to SX1208-Datasheet for register description */
- sx1208_write(REG_RXBW, 0x55);
- sx1208_write(REG_AFCBW, 0x8B);
- sx1208_write(REG_DIOMAPPING2, 0x07);
- for(i=0; i<8; i++){
- sx1208_write(REG_SYNCVALUE1+i, 0x01); // Write SyncWord to default value
- }
- sx1208_write(REG_FIFOTHRESH, 0x8F);
- /** Receiver optimized */
- sx1208_write(REG_TESTLNA, 0X2D); // =0x2D,enable sensitivity boost, this is optional
- // =0x1B,disable sensitivity boost
- {
- /* read test */
- // uint8_t read_reg;
- // read_reg = sx1208_read(REG_RSSITHRESH);
- // read_reg = sx1208_read(REG_PACKETCONFIG2);
- // read_reg = sx1208_read(REG_TESTLNA);
- // read_reg = sx1208_read(REG_TESTLNA);
- }
- {
- //LNA \AGC config
- sx1208_write(REG_LNA, 0X89); // 0x89 means 200 Ohm LNA and AGC OFF with G1
- sx1208_write(REG_DAGC, 0x30); //
- }
- {
- sx1208_write(REG_RSSITHRESH, 0xE8); // =0xE8,Auto threshold:
- sx1208_write(REG_PACKETCONFIG2, 0x04); // .AutoRxRestartOn = 1,
- }
- // sx1208_write(REG_RSSICONFIG, sx1208_read(REG_RSSICONFIG) | RF_RSSI_START);
- {
- // uint8_t i = 0;
- // /** configure DIO Mapping */
- // sx1208_write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00 | \
- // RF_DIOMAPPING1_DIO1_00 | \
- // RF_DIOMAPPING1_DIO2_00 | \
- // RF_DIOMAPPING1_DIO3_FIFO_FULL );
- // //fifo总共66BYTE,写完DIO3会拉高
- // while(READ_RF_SX12xx_DIO3() == 0)
- // {
- // sx1208_write(REG_FIFO, 0xff);
- // i ++;
- // if (i >= 66)
- // {
- // break;
- // }
-
- // }
- // delay_ms(10);
- // //FifoOverrun位写1,DIO3会置低,不操作该bit,电平会一直保持
- // sx1208_write(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN);
- // while (1)
- // {
- // ;
- // }
-
- }
- delay_ms(10);
- }
- void sx1208_set_mode(sx1208_mode_t mode)
- {
- uint8_t cur_mode;
- cur_mode = sx1208_read(REG_OPMODE) & (~RF_OPMODE_MASK);
- if(cur_mode != mode){
- /** adjust high power option, must be closed during RX */
- switch(mode){
- case RF_OPMODE_TRANSMITTER:
- if( sx1208_high_power && (sx1208_read(REG_OCP) != 0x0F) ){
- sx1208_write(REG_OCP, 0x0F);
- sx1208_write(REG_TEST_PA1, 0x5D);
- sx1208_write(REG_TEST_PA2, 0x7C);
- }
- break;
- case RF_OPMODE_RECEIVER:
- if( sx1208_high_power && (sx1208_read(REG_OCP) != 0x1F) ){
- sx1208_write(REG_OCP, 0x1F);
- sx1208_write(REG_TEST_PA1, 0x55);
- sx1208_write(REG_TEST_PA2, 0x70);
- }
- break;
- default:
- break;
- }
- sx1208_rmw(REG_OPMODE, RF_OPMODE_MASK, mode);
- }
- while( (sx1208_read(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00 );
- }
- void sx1208_set_config(sx1208_config_t *config)
- {
- sx1208_protocol = config->protocol;
- sx1208_set_frf(config->frf);
- sx1208_set_fdev(config->fdev);
- sx1208_set_bitrate(config->bitrate);
- sx1208_set_rxbw(config->fdev, config->bitrate);
- sx1208_set_tx_power(config->tx_power);
- sx1208_set_sync_word(config->sync_word, config->sync_word_len);
- switch(sx1208_protocol){
- case SX1208_PROTOCOL_STATE_GRID:
- /** To implement state grid protocol, we need use software crc and fixed length packet */
- sx1208_set_header_mode(SX1208_HEADER_DISABLE);
- sx1208_set_crc_mode(SX1208_CRC_OFF);
- sx1208_write(REG_PAYLOADLENGTH, SX1208_PAYLOAD_LENGTH_MAX);
- break;
- case SX1208_PROTOCOL_NONE:
- sx1208_set_header_mode(config->header_mode);
- if(config->header_mode == SX1208_HEADER_DISABLE){
- sx1208_write(REG_PAYLOADLENGTH, config->payload_len);
- }
- sx1208_set_crc_mode(config->crc_mode);
- break;
- }
- /** If CRC AUTO CLEAR is on, then there will be not PKT_READY interrupt, when crc is error
- Turn it off to make sure PKT_READY is generated at any time */
- sx1208_set_crc_auto_clear(SX1208_CRC_AUTO_CLEAR_OFF);
- sx1208_set_preamble(SX1208_TX_PREAMBLE, config->tx_preamble_len);
- sx1208_set_preamble(SX1208_RX_PREAMBLE, config->rx_preamble_len);
- }
- int8_t sx1208_send(uint8_t *buf, uint8_t len, uint16_t timeout)
- {
- int i;
- uint8_t mode;
- uint16_t crc;
- uint8_t frame_length;
- mode = sx1208_read(REG_OPMODE) & (~RF_OPMODE_MASK);
- if( mode == RF_OPMODE_TRANSMITTER || mode == RF_OPMODE_RECEIVER ){
- return -1;
- }
- if(len == 0){
- return -2;
- }
- /** TX start is triggered by FifoLevel */
- if(len > SX1208_TX_FIFO_THRESH){
- /** set fifo threshold for TX mode, make a software FIFO ALMOST Empty INTERRUPT*/
- sx1208_write(REG_FIFOTHRESH, SX1208_TX_FIFO_THRESH);
- }else{
- sx1208_write(REG_FIFOTHRESH, len-1);
- }
- /** rewrite tx_preamble length to preamble length register */
- sx1208_set_preamble_reg(sx1208_tx_preamble_len_g);
- /** configure DIO Mapping */
- sx1208_write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_PKT_SENT | \
- RF_DIOMAPPING1_DIO1_FIFO_LEVEL | \
- RF_DIOMAPPING1_DIO2_FIFO_NEMPTY | \
- RF_DIOMAPPING1_DIO3_FIFO_FULL );
- switch(sx1208_protocol){
- case SX1208_PROTOCOL_STATE_GRID:
- /** State Grid Length area, length of payload */
- sx1208_write(REG_FIFO, sx1208_state_grid_whitening_reverse_data(len, 0)); // Use index 0 to whitening the first byte (length).
- /** State Grid Whole Frame Length, 1 byte for length, 2 bytes for CRC, "len" bytes for payload */
- sx1208_write(REG_PAYLOADLENGTH, len+3);
- /** calculate and append crc bytes */
- crc = sx1208_state_grid_crc_calc(buf, len);
- buf[len] = (uint8_t)crc;
- buf[len+1] = (uint8_t)(crc>>8);
- /** recalculate frame length */
- frame_length = len + 2;
- sx1208_state_grid_whitening_reverse_buf(buf, frame_length, 1); // Use index 1 to whitening and reverse payload and crc
- break;
- case SX1208_PROTOCOL_NONE:
- if(sx1208_read(REG_PACKETCONFIG1) & RF_PACKET1_FORMAT_VARIABLE){
- sx1208_write(REG_FIFO, len);
- }else{
- sx1208_write(REG_PAYLOADLENGTH, len);
- }
- /** recalculate frame length */
- frame_length = len;
- break;
- }
- i=0;
- while(READ_RF_SX12xx_DIO3() == 0){
- sx1208_write(REG_FIFO, buf[i]);
- i++;
- if(i >= frame_length){
- break;
- }
- }
- // TODO: protect this section code
- /** i shouldn't be re-initialized */
- for(; i<frame_length; i++){
- sx1208_ext_fifo[sx1208_ext_fifo_wr_index++] = buf[i];
- sx1208_ext_fifo_count++;
- }
- /** resume buffer data */
- sx1208_state_grid_reverse_whitening_buf(buf, frame_length, 1);
- sx1208_set_mode(SX1208_MODE_TX);
- return 0;
- }
- void sx1208_receive(uint8_t *buf, uint8_t len, uint16_t timeout)
- {
- /** For protection */
- sx1208_set_mode(SX1208_MODE_SLEEP);
- sx1208_write(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN);
- /** set fifo threshold for RX mode, make a software FIFO ALMOST FULL INTERRUPT*/
- sx1208_write(REG_FIFOTHRESH, SX1208_RX_FIFO_THRESH);
- /** rewrite tx_preamble length to preamble length register */
- sx1208_set_preamble_reg(sx1208_rx_preamble_len_g);
- /** configure DIO Mapping */
- sx1208_write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_PLD_RDY | \
- RF_DIOMAPPING1_DIO1_FIFO_LEVEL | \
- RF_DIOMAPPING1_DIO2_FIFO_NEMPTY | \
- RF_DIOMAPPING1_DIO3_PREAMBLEDETECT );
- switch(sx1208_protocol){
- case SX1208_PROTOCOL_STATE_GRID:
- sx1208_set_header_mode(SX1208_HEADER_DISABLE);
- /** force receive largest packets, use software to check when exits. */
- sx1208_write(REG_PAYLOADLENGTH, SX1208_PAYLOAD_LENGTH_MAX);
- break;
- case SX1208_PROTOCOL_NONE:
- if(sx1208_read(REG_PACKETCONFIG1) & RF_PACKET1_FORMAT_VARIABLE){
- /** variable mode could receive maximum 255 bytes payload */
- sx1208_write(REG_PAYLOADLENGTH, SX1208_PAYLOAD_LENGTH_MAX);
- }else{
- sx1208_write(REG_PAYLOADLENGTH, len);
- }
- break;
- }
- sx1208_ext_fifo_rd_index = 0;
- sx1208_ext_fifo_count = 0;
- sx1208_ext_fifo_wr_index = 0;
- sx1208_rx_pkt.buf = buf;
- sx1208_set_mode(SX1208_MODE_RX);
- delay_ms(1);
- }
- void sx1208_rx_test_mode(void)
- {
- sx1208_set_mode(SX1208_MODE_STANDBY);
- delay_ms(20);
- sx1208_set_mode(SX1208_MODE_FS);
- delay_ms(20);
- sx1208_write(REG_DATAMODUL,0x40); // continuous mode
- delay_ms(10);
- /** configure DIO Mapping */
- sx1208_write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_PLD_RDY | \
- RF_DIOMAPPING1_DIO1_FIFO_LEVEL | \
- RF_DIOMAPPING1_DIO2_01 | \
- RF_DIOMAPPING1_DIO3_PREAMBLEDETECT );
- // sx1208_write(REG_DIOMAPPING1,0x00);
- // delay_ms(10);
- sx1208_write(REG_DIOMAPPING2,0x07);
- delay_ms(10);
- sx1208_set_mode(SX1208_MODE_RX);
- delay_ms(20);
- while((sx1208_read(REG_IRQFLAGS1)&RF_IRQFLAGS1_RXREADY)==0);
- }
- void sx1208_tx_test_mode(void)
- {
- sx1208_set_mode(SX1208_MODE_STANDBY);
- delay_ms(20);
- sx1208_set_mode(SX1208_MODE_FS);
- // delay_ms(20);
- // sx1208_write(REG_DATAMODUL,0x40); // continuous mode
- // delay_ms(10);
- // sx1208_write(REG_DIOMAPPING1,0x00);
- // delay_ms(10);
- // sx1208_write(REG_DIOMAPPING2,0x07);
- delay_ms(10);
- sx1208_set_mode(SX1208_MODE_TX);
- delay_ms(20);
- while((sx1208_read(REG_IRQFLAGS1)&RF_IRQFLAGS1_TXREADY)==0);
- }
- void sx1208_set_rxtx_polarity(sx1208_txtx_polarity_t pol)
- {
- if(pol == SX1208_RXTX_TXHIGH || pol == SX1208_RXTX_RXLOW){
- sx1208_rmw(REG_OPMODE, RF_OPMODE_RXTX_MASK, RF_OPMODE_RXTX_TXHIGH);
- }else{
- sx1208_rmw(REG_OPMODE, RF_OPMODE_RXTX_MASK, RF_OPMODE_RXTX_RXHIGH);
- }
- }
- void sx1208_set_frf( uint32_t frf )
- {
- frf = ( uint32_t )( ( double )frf / ( double )SX1208_FREQ_STEP );
- sx1208_write( REG_FRFMSB, ( uint8_t )( ( frf >> 16 ) & 0xFF ) );
- sx1208_write( REG_FRFMID, ( uint8_t )( ( frf >> 8 ) & 0xFF ) );
- sx1208_write( REG_FRFLSB, ( uint8_t )( frf & 0xFF ) );
- }
- void sx1208_set_fdev( uint32_t fdev )
- {
- if(fdev>100000){
- fdev=100000;
- }
- fdev = ( uint32_t )( ( double )fdev / ( double )SX1208_FREQ_STEP );
- sx1208_write( REG_FDEVMSB, ( uint8_t )( ( fdev >> 8 ) & 0xFF ) );
- sx1208_write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) );
- }
- void sx1208_set_bitrate( uint32_t br )
- {
- if(br>100000){
- br=100000;
- }
- br = ( uint32_t )( ( double )SX1208_FXOSC / ( double )br );
- sx1208_write( REG_BITRATEMSB, ( uint8_t )( ( br >> 8 ) & 0xFF ) );
- sx1208_write( REG_BITRATELSB, ( uint8_t )( br & 0xFF ) );
- }
- void sx1208_set_rxbw(uint32_t fdev, uint32_t br)
- {
- uint8_t reg, RxBwMant, RxBwExp, i;
- uint32_t sum;
- sum = fdev * 2 + br;
- for(i=0; i<SX1208_FSK_RXBW_TAB_LENGTH; i++){
- if(sx1208_fsk_rxbw_tab[i] > sum){
- break;
- }
- }
- if(i == SX1208_FSK_RXBW_TAB_LENGTH){
- // invalid fdev and bitrate (Fdev + bitrate/2 > RxBw)
- // fdev and bitrate are out of range, use the largest RXBW
- i = (SX1208_FSK_RXBW_TAB_LENGTH-1);
- }
- RxBwExp = 7 - i/3;
- RxBwMant = 2 - i%3;
- reg = sx1208_read(REG_RXBW);
- reg = (reg&RF_RXBW_DCCFREQ_111) | (RxBwMant<<3) | RxBwExp;
- sx1208_write(REG_RXBW, reg);
- }
- sx1208_tx_port_t hal_sx1208_get_tx_port(void)
- {
- #if 0
- /** use RFIO as OUTPUT port*/
- return SX1208_TX_PORT_RFIO;
- #else
- /** use PA_BOOST as OUTPUT port */
- return SX1208_TX_PORT_PA_BOOST;
- #endif
- }
- void sx1208_set_tx_power( int8_t pow )
- {
- uint8_t reg = 0;
- uint8_t OutputPower;
- /** reset power setings, start TX power configuration from exact state */
- sx1208_write(REG_PALEVEL, 0x9F);
- /** disable high power output */
- sx1208_write(REG_OCP, 0x1F);
- sx1208_write(REG_TEST_PA1, 0x55);
- sx1208_write(REG_TEST_PA2, 0x70);
- sx1208_high_power = 0;
- if( hal_sx1208_get_tx_port() == SX1208_TX_PORT_PA_BOOST ){
- /** Adjust power value if it is out of range */
- if(pow>20){
- pow = 20;
- }else if(pow < 2){
- pow = 2;
- }
- /** TX on PA_BOOST, this driver doesn't support to use PA1 alone
- Use PA1 only with PA_BOOST, HW should be different with use both PA1 and PA2*/
- if(pow<=17){
- if (pow<=13)
- {
- reg = RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_OFF;
- OutputPower = 18 + pow;
- }
- else
- {
- /** Enable both PA1 and PA2 on PA_BOOST */
- reg = RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_ON;
- OutputPower = 14 + pow;
- }
- }else{
- /** Enable both PA1 and PA2 on PA_BOOST, and enable high power output */
- reg = RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_ON;
- sx1208_write(REG_OCP, 0x0F);
- sx1208_write(REG_TEST_PA1, 0x5D);
- sx1208_write(REG_TEST_PA2, 0x7C);
- OutputPower = 11 + pow;
- sx1208_high_power = 1; // high power mode
- }
- }else{
- /** TX on RFIO */
- if(pow>13){
- pow = 13;
- }else if(pow < -18){
- pow = -18;
- }
- /** Enable PA0 on RFIO */
- reg = RF_PALEVEL_PA0_ON;
- OutputPower = 18 + pow;
- }
- reg |= OutputPower;
- sx1208_write(REG_PALEVEL, reg);
- }
- void sx1208_set_sync_word(uint8_t *sync_word, uint8_t len)
- {
- int8_t i;
- if(len == 0 || sync_word == NULL){
- sx1208_rmw(REG_SYNCCONFIG, RF_SYNC_MASK, RF_SYNC_OFF);
- for(i = 0; i<8; i++){
- sx1208_write(REG_SYNCVALUE1+i, 0x00);
- }
- }else if(len <= 8){
- sx1208_rmw(REG_SYNCCONFIG, RF_SYNC_MASK, RF_SYNC_ON); // sync word on
- sx1208_rmw(REG_SYNCCONFIG, RF_SYNC_SIZE_MASK, (len-1)<<3); // sync word size
- for(i = 0; i<len; i++){
- switch(sx1208_protocol){
- case SX1208_PROTOCOL_STATE_GRID:
- /** SX1208 send MSB first, StateGrid send LSB first, reverse sync word to implement State Grid Spec. */
- sx1208_write(REG_SYNCVALUE1+i, sx1208_state_grid_reverse(sync_word[i]));
- break;
- case SX1208_PROTOCOL_NONE:
- sx1208_write(REG_SYNCVALUE1+i, sync_word[i]);
- break;
- }
- }
- }else{
- while(1); // synword length is less than 8
- }
- }
- void sx1208_set_header_mode(sx1208_header_mode_t hdr_mode)
- {
- if(hdr_mode == SX1208_HEADER_ENABLE){
- /** Packet with header */
- sx1208_rmw(REG_PACKETCONFIG1, RF_PACKET1_FORMAT_MASK, RF_PACKET1_FORMAT_VARIABLE);
- }else{
- /** Packet without header */
- sx1208_rmw(REG_PACKETCONFIG1, RF_PACKET1_FORMAT_MASK, RF_PACKET1_FORMAT_FIXED);
- }
- }
- void sx1208_set_crc_mode(sx1208_crc_mode_t crc_mode)
- {
- if(crc_mode == SX1208_CRC_ON){
- sx1208_rmw(REG_PACKETCONFIG1, RF_PACKET1_CRC_MASK, RF_PACKET1_CRC_ON);
- }else{
- sx1208_rmw(REG_PACKETCONFIG1, RF_PACKET1_CRC_MASK, RF_PACKET1_CRC_OFF);
- }
- }
- void sx1208_set_crc_auto_clear(sx1208_crc_auto_clear_t crcac_opt)
- {
- if(crcac_opt == SX1208_CRC_AUTO_CLEAR_ON){
- sx1208_rmw(REG_PACKETCONFIG1, RF_PACKET1_CRCAUTOCLEAR_MASK, RF_PACKET1_CRCAUTOCLEAR_ON);
- }else{
- sx1208_rmw(REG_PACKETCONFIG1, RF_PACKET1_CRCAUTOCLEAR_MASK, RF_PACKET1_CRCAUTOCLEAR_OFF);
- }
- }
- uint8_t sx1208_read_rssi(void)
- {
- // sx1208_write(REG_RSSICONFIG, sx1208_read(REG_RSSICONFIG) | RF_RSSI_START);
- // while( 0 == ( sx1208_read(REG_RSSICONFIG) & RF_RSSI_DONE ) );
- return sx1208_read(REG_RSSIVALUE);
- }
- uint8_t sx1208_read_fei(void)
- {
- // sx1208_write(REG_RSSICONFIG, sx1208_read(REG_RSSICONFIG) | RF_RSSI_START);
- while( 0 == ( sx1208_read(REG_RSSICONFIG) & RF_RSSI_DONE ) );
- return sx1208_read(REG_RSSIVALUE);
- }
- void sx1208_set_preamble(sx1208_preamble_t preamble_type, uint16_t len)
- {
- if(preamble_type == SX1208_TX_PREAMBLE){
- sx1208_tx_preamble_len_g = len;
- }else{
- sx1208_rx_preamble_len_g = len;
- }
- }
- static void sx1208_set_preamble_reg(uint16_t len)
- {
- sx1208_write(REG_PREAMBLEMSB, (uint8_t)(len>>8));
- sx1208_write(REG_PREAMBLELSB, (uint8_t)len);
- }
- /** low level functions */
- uint8_t sx1208_read(uint8_t addr)
- {
- uint8_t ret;
- BOARD_SPI_NSS_L();
- SpiReadWrite( (~0x80) & addr );
- ret = SpiReadWrite( 0x00 );
- BOARD_SPI_NSS_H();
- return ret;
- }
- void sx1208_write(uint8_t addr, uint8_t data)
- {
- BOARD_SPI_NSS_L();
- SpiReadWrite( 0x80 | addr );
- SpiReadWrite( data );
- BOARD_SPI_NSS_H();
- }
- uint8_t sx1208_read_int(uint8_t addr)
- {
- uint8_t ret;
- BOARD_SPI_NSS_L();
- SpiReadWrite( (~0x80) & addr );
- ret = SpiReadWrite( 0x00 );
- BOARD_SPI_NSS_H();
- return ret;
- }
- void sx1208_write_int(uint8_t addr, uint8_t data)
- {
- BOARD_SPI_NSS_L();
- SpiReadWrite( 0x80 | addr );
- SpiReadWrite( data );
- BOARD_SPI_NSS_H();
- }
- /** read-modify write register */
- void sx1208_rmw(uint8_t addr, uint8_t mask, uint8_t val)
- {
- uint8_t ret;
- /** read register */
- BOARD_SPI_NSS_L();
- SpiReadWrite( (~0x80) & addr );
- ret = SpiReadWrite( 0x00 );
- BOARD_SPI_NSS_H();
- /** modify the data */
- ret = (ret & mask) | (val & ~mask);
- /** write data back */
- BOARD_SPI_NSS_L();
- SpiReadWrite( 0x80 | addr );
- SpiReadWrite( ret );
- BOARD_SPI_NSS_H();
- }
- /** read-modify write register */
- void sx1208_rmw_int(uint8_t addr, uint8_t mask, uint8_t val)
- {
- uint8_t ret;
- /** read register */
- BOARD_SPI_NSS_L();
- SpiReadWrite( (~0x80) & addr );
- ret = SpiReadWrite( 0x00 );
- BOARD_SPI_NSS_H();
- /** modify the data */
- ret = (ret & mask) | (val & ~mask);
- /** write data back */
- BOARD_SPI_NSS_L();
- SpiReadWrite( 0x80 | addr );
- SpiReadWrite( ret );
- BOARD_SPI_NSS_H();
- }
- void sx1208_rmw_bit(uint8_t addr, uint8_t bit, uint8_t val)
- {
- uint8_t ret;
- /** read register */
- BOARD_SPI_NSS_L();
- SpiReadWrite( (~0x80) & addr );
- ret = SpiReadWrite( 0x00 );
- BOARD_SPI_NSS_H();
- /** modify the data */
- ret = (val == 0)? (ret & bit) : (ret | bit);
- /** write data back */
- BOARD_SPI_NSS_L();
- SpiReadWrite( 0x80 | addr );
- SpiReadWrite( ret );
- BOARD_SPI_NSS_H();
- }
- void sx1208_read_burst(uint8_t addr, uint8_t *buf, uint16_t len)
- {
- int i;
- BOARD_SPI_NSS_L();
- SpiReadWrite( (~0x80) & addr );
- for(i = 0; i<len; i++){
- buf[i] = SpiReadWrite( 0x00 );
- }
- BOARD_SPI_NSS_H();
- }
- void sx1208_write_burst(uint8_t addr, uint8_t *buf, uint16_t len)
- {
- int i;
- BOARD_SPI_NSS_L();
- SpiReadWrite( 0x80 | addr );
- for(i = 0; i<len; i++){
- SpiReadWrite( *buf++ );
- }
- BOARD_SPI_NSS_H();
- }
- int sx1208_read_fifo(uint8_t *buf, uint16_t len)
- {
- int i = 0;
- BOARD_SPI_NSS_L();
- SpiReadWrite( (~0x80) & REG_FIFO );
- while( (READ_RF_SX12xx_DIO2() == 1) && (i < len) ){
- buf[i] = SpiReadWrite( 0x00 );
- i++;
- }
- BOARD_SPI_NSS_H();
- return i;
- }
- int sx1208_write_fifo(uint8_t *buf, uint16_t len)
- {
- sx1208_write_burst(REG_FIFO, buf, len);
- return 0;
- }
- static int sx1208_update_fifo_thresh(uint16_t pkt_len, uint8_t received_len)
- {
- uint16_t remain_len;
- remain_len = pkt_len - received_len;
- if( remain_len > SX1208_RX_FIFO_THRESH ){
- sx1208_write_int(REG_FIFOTHRESH, SX1208_RX_FIFO_THRESH);
- }else if(remain_len < 5){
- return -1;
- }else{
- sx1208_write_int(REG_FIFOTHRESH, remain_len-2);
- }
- return 0;
- }
- void sx1208_onDioIrq( void )
- {
- Irq0Fired = true;
- }
- void sx1208_process(void)
- {
- uint8_t irq_flag2, mode, crc_sta;
- if (Irq0Fired == true)
- {
- Irq0Fired = false;
- irq_flag2 = sx1208_read_int(REG_IRQFLAGS2);
- mode = sx1208_read_int(REG_OPMODE) & (~RF_OPMODE_MASK);
- crc_sta = sx1208_read_int(REG_PACKETCONFIG1) & (~RF_PACKET1_CRC_MASK);
-
- switch(mode){
- case RF_OPMODE_TRANSMITTER:
- if(irq_flag2 & RF_IRQFLAGS2_PACKETSENT){
- /** package sent, exit */
- sx1208_rmw_int(REG_OPMODE, RF_OPMODE_MASK, RF_OPMODE_SLEEP);
- while( (sx1208_read_int(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00 );
- sx1208_callback_g(SX1208_TX_DONE, NULL);
- }
- break;
- case RF_OPMODE_RECEIVER:
- if( (irq_flag2 & RF_IRQFLAGS2_PAYLOADREADY) &&( (!crc_sta) || (irq_flag2 & RF_IRQFLAGS2_CRCOK) ) ){
- while( (READ_RF_SX12xx_DIO2() == 1) && (sx1208_ext_fifo_count < 256) ){
- sx1208_ext_fifo[sx1208_ext_fifo_wr_index++] = sx1208_read_int(REG_FIFO);
- sx1208_ext_fifo_count++;
- }
- sx1208_rx_pkt.raw_rssi = sx1208_read_int(REG_RSSIVALUE);
- switch(sx1208_protocol){
- case SX1208_PROTOCOL_STATE_GRID:
- /** should never here */
- if( SX1208_STATE_GRID_GOOD_CRC == sx1208_state_grid_crc_check((void *)(sx1208_ext_fifo+1), sx1208_rx_payload_length-3) ){
- memcpy(sx1208_rx_pkt.buf, (void *)(sx1208_ext_fifo+1), sx1208_ext_fifo_count-1);
- sx1208_rx_pkt.len = sx1208_ext_fifo_count-3;
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_DONE, &sx1208_rx_pkt);
- }else{
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_ERROR, NULL);
- }
- break;
- case SX1208_PROTOCOL_NONE:
- memcpy(sx1208_rx_pkt.buf, (void *)(sx1208_ext_fifo+1), sx1208_ext_fifo_count-1);
- sx1208_rx_pkt.len = sx1208_ext_fifo_count-1;
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_DONE, &sx1208_rx_pkt);
- break;
- }
- }else{
- /** CRC error */
- /** package received, exit */
- sx1208_rmw_int(REG_OPMODE, RF_OPMODE_MASK, RF_OPMODE_SLEEP);
- while( (sx1208_read_int(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00 );
- sx1208_ext_fifo_count = 0;
- sx1208_ext_fifo_wr_index = 0;
- sx1208_callback_g(SX1208_RX_ERROR, NULL);
- }
- break;
- default:
- break;
- }
- }
- }
- void sx1208_irq_dio0(void)
- {
- uint8_t irq_flag2, mode, crc_sta;
- irq_flag2 = sx1208_read_int(REG_IRQFLAGS2);
- mode = sx1208_read_int(REG_OPMODE) & (~RF_OPMODE_MASK);
- crc_sta = sx1208_read_int(REG_PACKETCONFIG1) & (~RF_PACKET1_CRC_MASK);
- switch(mode){
- case RF_OPMODE_TRANSMITTER:
- if(irq_flag2 & RF_IRQFLAGS2_PACKETSENT){
- /** package sent, exit */
- sx1208_rmw_int(REG_OPMODE, RF_OPMODE_MASK, RF_OPMODE_SLEEP);
- while( (sx1208_read_int(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00 );
- sx1208_callback_g(SX1208_TX_DONE, NULL);
- }
- break;
- case RF_OPMODE_RECEIVER:
- if( (irq_flag2 & RF_IRQFLAGS2_PAYLOADREADY) &&( (!crc_sta) || (irq_flag2 & RF_IRQFLAGS2_CRCOK) ) ){
- while( (READ_RF_SX12xx_DIO2() == 1) && (sx1208_ext_fifo_count < 256) ){
- sx1208_ext_fifo[sx1208_ext_fifo_wr_index++] = sx1208_read_int(REG_FIFO);
- sx1208_ext_fifo_count++;
- }
- /** package received, exit receive mode */
- sx1208_rmw_int(REG_OPMODE, RF_OPMODE_MASK, RF_OPMODE_SLEEP);
- while( (sx1208_read_int(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00 );
- switch(sx1208_protocol){
- case SX1208_PROTOCOL_STATE_GRID:
- /** should never here */
- if( SX1208_STATE_GRID_GOOD_CRC == sx1208_state_grid_crc_check((void *)(sx1208_ext_fifo+1), sx1208_rx_payload_length-3) ){
- memcpy(sx1208_rx_pkt.buf, (void *)(sx1208_ext_fifo+1), sx1208_ext_fifo_count-1);
- sx1208_rx_pkt.len = sx1208_ext_fifo_count-3;
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_DONE, &sx1208_rx_pkt);
- }else{
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_ERROR, NULL);
- }
- break;
- case SX1208_PROTOCOL_NONE:
- memcpy(sx1208_rx_pkt.buf, (void *)(sx1208_ext_fifo+1), sx1208_ext_fifo_count-1);
- sx1208_rx_pkt.len = sx1208_ext_fifo_count-1;
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_DONE, &sx1208_rx_pkt);
- break;
- }
- }else{
- /** CRC error */
- /** package received, exit */
- sx1208_rmw_int(REG_OPMODE, RF_OPMODE_MASK, RF_OPMODE_SLEEP);
- while( (sx1208_read_int(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00 );
- sx1208_ext_fifo_count = 0;
- sx1208_ext_fifo_wr_index = 0;
- sx1208_callback_g(SX1208_RX_ERROR, NULL);
- }
- break;
- default:
- break;
- }
- }
- void sx1208_irq_dio1(void)
- {
- uint8_t irq_flag2, mode, len;
- uint16_t fifo_bytes_remain;
- irq_flag2 = sx1208_read_int(REG_IRQFLAGS2);
- mode = sx1208_read_int(REG_OPMODE) & (~RF_OPMODE_MASK);
- switch(mode){
- case RF_OPMODE_TRANSMITTER:
- if(irq_flag2 & RF_IRQFLAGS2_FIFOLEVEL){
- /** rising edge */
- }else{
- /** falling edge, FIFO almost empty */
- while( (READ_RF_SX12xx_DIO3() == 0) && (sx1208_ext_fifo_count > 0) ){
- sx1208_write_int(REG_FIFO, sx1208_ext_fifo[sx1208_ext_fifo_rd_index++]);
- sx1208_ext_fifo_count--;
- }
- }
- break;
- case RF_OPMODE_RECEIVER:
- if(irq_flag2 & RF_IRQFLAGS2_FIFOLEVEL){
- /** rising edge */
- fifo_bytes_remain = 256 - sx1208_ext_fifo_count;
- fifo_bytes_remain = sx1208_rx_payload_length;
- len = sx1208_read_fifo( (uint8_t *)sx1208_ext_fifo + (uint8_t)sx1208_ext_fifo_wr_index, fifo_bytes_remain );
- sx1208_ext_fifo_wr_index += len;
- sx1208_ext_fifo_count += len;
- switch(sx1208_protocol){
- case SX1208_PROTOCOL_STATE_GRID:
- if(sx1208_update_fifo_thresh(sx1208_rx_payload_length, sx1208_ext_fifo_count) < 0){
- while(sx1208_ext_fifo_count < sx1208_rx_payload_length){
- len = sx1208_read_fifo( (uint8_t *)sx1208_ext_fifo + (uint8_t)sx1208_ext_fifo_wr_index, sx1208_rx_payload_length );
- sx1208_ext_fifo_wr_index += len;
- sx1208_ext_fifo_count += len;
- }
- /** package received, exit */
- sx1208_rmw_int(REG_OPMODE, RF_OPMODE_MASK, RF_OPMODE_SLEEP);
- while( (sx1208_read_int(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00 );
- sx1208_state_grid_reverse_whitening_buf((void *)sx1208_ext_fifo, sx1208_rx_payload_length ,0);
- if( SX1208_STATE_GRID_GOOD_CRC == sx1208_state_grid_crc_check((void *)(sx1208_ext_fifo+1), sx1208_rx_payload_length-3) ){
- memcpy(sx1208_rx_pkt.buf, (void *)(sx1208_ext_fifo+1), sx1208_ext_fifo_count-1);
- sx1208_rx_pkt.len = sx1208_ext_fifo_count-3;
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_DONE, &sx1208_rx_pkt);
- }else{
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_ERROR, NULL);
- }
- }
- break;
- case SX1208_PROTOCOL_NONE:
- break;
- }
- }else{
- /** falling edge */
- }
- break;
- default:
- break;
- }
- }
- void sx1208_irq_dio2(void)
- {
- uint8_t irq_flag2, mode, len;
- irq_flag2 = sx1208_read_int(REG_IRQFLAGS2);
- mode = sx1208_read_int(REG_OPMODE) & (~RF_OPMODE_MASK);
- switch(mode){
- case RF_OPMODE_TRANSMITTER:
- break;
- case RF_OPMODE_RECEIVER:
- if(irq_flag2 & RF_IRQFLAGS2_FIFONOTEMPTY){
- /** rising edge */
- switch(sx1208_protocol){
- case SX1208_PROTOCOL_STATE_GRID:
- /** read first byte back, this byte is the length of this frame */
- if(sx1208_ext_fifo_wr_index == 0){
- sx1208_read_fifo( (uint8_t *)sx1208_ext_fifo + (uint8_t)sx1208_ext_fifo_wr_index, 1 );
- sx1208_rx_payload_length = sx1208_state_grid_reverse_whitening_data(sx1208_ext_fifo[0], 0)+3;
- /** payload length is out of range */
- if(sx1208_rx_payload_length > 0xFF){
- sx1208_rmw_int(REG_OPMODE, RF_OPMODE_MASK, RF_OPMODE_SLEEP);
- while( (sx1208_read_int(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00 );
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_ERROR, NULL);
- break;
- }
- sx1208_ext_fifo_wr_index++;
- sx1208_ext_fifo_count++;
- if(sx1208_update_fifo_thresh(sx1208_rx_payload_length, sx1208_ext_fifo_count) < 0){
- while(sx1208_ext_fifo_count < sx1208_rx_payload_length){
- len = sx1208_read_fifo( (uint8_t *)sx1208_ext_fifo + (uint8_t)sx1208_ext_fifo_wr_index, sx1208_rx_payload_length );
- sx1208_ext_fifo_wr_index += len;
- sx1208_ext_fifo_count += len;
- }
- /** package received, exit */
- sx1208_rmw_int(REG_OPMODE, RF_OPMODE_MASK, RF_OPMODE_SLEEP);
- while( (sx1208_read_int(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00 );
- sx1208_state_grid_reverse_whitening_buf((void *)sx1208_ext_fifo, sx1208_rx_payload_length ,0);
- if( SX1208_STATE_GRID_GOOD_CRC == sx1208_state_grid_crc_check((void *)(sx1208_ext_fifo+1), sx1208_rx_payload_length-3) ){
- memcpy(sx1208_rx_pkt.buf, (void *)(sx1208_ext_fifo+1), sx1208_ext_fifo_count-1);
- sx1208_rx_pkt.len = sx1208_ext_fifo_count-3;
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_DONE, &sx1208_rx_pkt);
- }else{
- sx1208_ext_fifo_count = 0;
- sx1208_callback_g(SX1208_RX_ERROR, NULL);
- }
- }
- }
- break;
- case SX1208_PROTOCOL_NONE:
- break;
- }
- }
- break;
- default:
- break;
- }
- }
- void sx1208_irq_dio3(void)
- {
- uint8_t irq_flag1, mode, afc_ctl;
- afc_ctl = sx1208_read_int(REG_AFCCTRL);
- irq_flag1 = sx1208_read_int(REG_IRQFLAGS1);
- mode = sx1208_read_int(REG_OPMODE) & (~RF_OPMODE_MASK);
- switch(mode){
- case RF_OPMODE_TRANSMITTER:
- break;
- case RF_OPMODE_RECEIVER:
- if(afc_ctl & RF_AFCCTRL_PREAMBLEDETECT){
- //sx1208_rx_pkt.raw_rssi = sx1208_read_rssi();
- sx1208_write_int(REG_RSSICONFIG, sx1208_read_int(REG_RSSICONFIG) | RF_RSSI_START);
- while( 0 == ( sx1208_read_int(REG_RSSICONFIG) & RF_RSSI_DONE ) );
- sx1208_rx_pkt.raw_rssi = sx1208_read_int(REG_RSSIVALUE);
- }else if(irq_flag1 & RF_IRQFLAGS1_SYNCADDRESSMATCH){
- //sx1208_rx_pkt.raw_rssi = sx1208_read_rssi();
- sx1208_write_int(REG_RSSICONFIG, sx1208_read_int(REG_RSSICONFIG) | RF_RSSI_START);
- while( 0 == ( sx1208_read_int(REG_RSSICONFIG) & RF_RSSI_DONE ) );
- sx1208_rx_pkt.raw_rssi = sx1208_read_int(REG_RSSIVALUE);
- }
- break;
- default:
- break;
- }
- }
- void sx1208_irq_dio4(void)
- {
- }
|