Обсуждаем приемники, передатчики, радиомикрофоны, жучки, генераторы, ВЧ-усилители, антенны и прочее радиохозяйство
Ответить

Re: Si4463 не взлетает

Пн сен 18, 2017 20:12:14

-выкинуть библиотеку от NiceRF для ардуино..))
-Или помехи при считывании с SI4463. Или при записи на SI4463.
-др.

Re: Si4463 не взлетает

Вт сен 19, 2017 17:56:28

А из-за плохой связи, из-за антенны может быть такое?

Re: Si4463 не взлетает

Вт сен 19, 2017 20:07:34

Если с библиотекой всё нормально (в чём я не уверен), то тогда ищите источник помех.
Конкретно с Si4463 пока не работал, только с другими модулями. Но разницы нет, т.к. все модули работают одинаково (по SPI).

-Из-за плохой связи могут быть ошибки при передачи пакетов по эфиру. Но во всех современных радиомодулях (включая Si4463) есть аппаратная проверка контрольной суммы. При этом вероятность приёма пакетов с ошибками (по эфиру) крайне низкая ... я бы сказал стремится к нулю)). Например при включенной CRC16, у меня ещё небыло случаев, чтобы радиомодуль принял пакет по эфиру с ошибками.
В другой теме экспериментировали с модулями. Радиомодуль может принимать пакеты с ошибка по эфиру, если например отключить проверку CRC и уменьшить длину преамбулы до 1 байт и длину адреса до 2...3 байт. В этом случае (при выключенном передатчике) приёмник радиомодуля синхронизируется по шуму эфира и выдаёт случайный набор битов)).

-Из-за антенны могут быть наводки от работающего передатчика (на полную мощность). Уже обсуждали, когда делали радиоуправляемый самолётик тут - viewtopic.php?f=28&t=141596
Врубаем передатчик на полную мощность - идут ошибки при чтении приёмниго буфера (по SPI) RFM23BP.
Потом поставили нормальную антенну и ошибки (помехи от передатчика) пропали)) Есть и другие варианты.

-Из-за помех от различных устройств могут быть ошибки. Например, когда делали радиоуправляемый кораблик, мы использовали nRF24L01. Там помехи были при работающем двигателе. Даже видео сняли)) Врубаем двигатель, зелёный светодиод на пульте мигает - идут ошибки при чтении приёмниго буфера (по SPI) nRF24L01. Помехи такие сильные, что аж сам модуль зависает )) Включается автоматическая перезагрузка модуля.)) https://www.youtube.com/watch?v=cQme_y4TORw
Потом запаяли сам радиомодуль nRF24L01 в экран и добавили фильт по питанию и фильтр на двигатель - ошибки (помехи от двигателя) пропали))

-Из-за плохого питания могут быть ошибки. Подключали к импульсному блоку питания, получили ошибки. Даже точно выяснили причину: импульсные помехи от блока питания по проводу MISO, по которому в МК приходят данные из приёмного буфера радиомодуля. ))
Поэтому на все модули ставят фильтры по питанию:
конденсаторы - обязательно. Дополнительные дросселя - желательно. Отдельные стабилизаторы - желательно. И т.д.
Короче, сделали нормальное питание - ошибки (мпульсные помехи от блока питания) пропали)) Гдето видео валяется))

-Ну и наверное самое главное: мы во всех схемах используем контрольные суммы. Считаем CRC в МК и добавляем к каждому пакету. При этом что бы не случилось (помехи по проводам, обрав проводов радиомодуля, отключение питания радиомодуля или падение питания ниже нормы... и т.д.) пакеты с ошибками у нас не проходят)) Т.е. ложных команд (в радиоуправляемых схемах) у нас нет.

Кратко вот. )) :tea:

P.S. А вообще... если ошибки идут часто, то источник помех обычно обнаруживается быстро)) Если есть приборы, то совсем хорошо))
Но обычно достаточно просто подключить радиомодуль напрямую к МК и погонять туда-сюда пустые пакеты, при разных условиях:
-на разной скорости SPI (маловероятно, но на всякий случай).
-на разной мощности передатчика (мин/макс).
-от отдельного источника питания (от батарей).
-при отключеном дополнительном оборудовании (всё лишнее отключить).
-и т.д.

Re: Si4463 не взлетает

Чт сен 21, 2017 08:27:49

Попробую погонять устройство дома, на столе, посмотрю будут ли идти такие глюки или нет.. Сейчас передающее устройство стоит в мастерской на другом конце огорода. Радиоприемник запитан сейчас от платы stm32f103c8t6(китай), по питанию si4463 поставил электролит 100 мкф и керамику 0.1 мкф. Кстати модуль радио такой rf4463pro он с экраном идет, заказывал с китая. БП AC-DC 220 в 5 на 3 Вата на него повесил электролит 680 мкф. Антенна спиралька. Все это дело на макетной плате и запихано в корпус от маршрутизатора.

И еще возник такой вопрос по настройке модуля. В даташите есть схема включения, где используется одна антенна на прием и передачу. И направление настраивается выводами gpio2 и gpio3. Это переключение происходит автоматически или надо в коде самому менять? Просто по библиотеки от NiceRF там настраивается один раз и больше в коде нигде не меняется.
Спойлер
Код:
// set antenna switch,in RF4463 is GPIO2 and GPIO3
// don't change setting of GPIO2,GPIO3,NIRQ,SDO
   buf[0]  = RF4463_GPIO_NO_CHANGE; //gpio0
   buf[1]  = RF4463_GPIO_NO_CHANGE; //gpio1
   buf[2]  = RF4463_GPIO_RX_STATE; //gpio2
   buf[3]  = RF4463_GPIO_TX_STATE; //gpio3
   buf[4]  = RF4463_NIRQ_INTERRUPT_SIGNAL;
   buf[5]  = RF4463_GPIO_SPI_DATA_OUT;
   setCommand(6,RF4463_CMD_GPIO_PIN_CFG,buf);


В библиотеке RadioHead при настройке модуля на прием или передачу настраиваются и выводы, но как я понял это gpio0 и gpio1 судя по коду. Так как там записывают два байта, а первые два байта в регистре GPIO_PIN_CFG 0x13 это gpio0 и gpio1.
Спойлер
Код:
void RH_RF24::setModeRx()
{
    if (_mode != RHModeRx)
    {
   // CAUTION: we cant clear the rx buffers here, else we set up a race condition
   // with the _rxBufValid test in available()

   // Tell the receiver the max data length we will accept (a TX may have changed it)
   uint8_t l[] = { sizeof(_buf) };
   set_properties(RH_RF24_PROPERTY_PKT_FIELD_2_LENGTH_7_0, l, sizeof(l));
   
   // Set the antenna switch pins using the GPIO, assuming we have an RFM module with antenna switch
   uint8_t gpio_config[] = { RH_RF24_GPIO_HIGH, RH_RF24_GPIO_LOW };
   command(RH_RF24_CMD_GPIO_PIN_CFG, gpio_config, sizeof(gpio_config));

   uint8_t rx_config[] = { 0x00, RH_RF24_CONDITION_RX_START_IMMEDIATE, 0x00, 0x00, _idleMode, _idleMode, _idleMode};
   command(RH_RF24_CMD_START_RX, rx_config, sizeof(rx_config));
   _mode = RHModeRx;
    }
}

void RH_RF24::setModeTx()
{
    if (_mode != RHModeTx)
    {
   // Set the antenna switch pins using the GPIO, assuming we have an RFM module with antenna switch
   uint8_t config[] = { RH_RF24_GPIO_LOW, RH_RF24_GPIO_HIGH };
   command(RH_RF24_CMD_GPIO_PIN_CFG, config, sizeof(config));

   uint8_t tx_params[] = { 0x00,
            (uint8_t)((_idleMode << 4) | RH_RF24_CONDITION_RETRANSMIT_NO | RH_RF24_CONDITION_START_IMMEDIATE)};
   command(RH_RF24_CMD_START_TX, tx_params, sizeof(tx_params));
   _mode = RHModeTx;
    }
}

Re: Si4463 не взлетает

Чт сен 21, 2017 17:34:49

В первой библиотеке выводы GPIO настроены на автоматическое переключение антенного коммутатора при изменении режима работы прием/передача. Во второй эти выводы настроены на ручное переключение из программы пользователя. Мой Вам совет - не пользуйтесь библиотеками написанными непонятно кем, лучше напишите свои. У меня по этим чипам статья есть здесь, а то что в ней не затронуто (нарпример переключение коммутатора) описано в документации на чип.

Re: Si4463 не взлетает

Ср янв 16, 2019 13:31:54

Всем доброго времени суток.
Просьба помочь новенькому :) До этого дальше ардуино с диодиками не ходил... Для реализации определенной задачи, начинаю разбираться с модулем сделанным в Китае (E30-170T20D). На нем стоит SI4463 ревизии 1B. Управляется он китайским аналогом STM8LG6. Прошивку пишу в IAR.
Собственно SI4463 "не взлетает" :)
Вроде поднял SPI между STM8L и SI4463 (если первой командой даю PART_INFO, то возвращаются байтики: 11 44 63 00 00 0F 00 03), но вот если подаю POWER_UP, то SI4463 перестаёт подавать признаки жизни, по SPI после READ_CMD_BUFF никогда не приходит CTS (0xFF), только 0. CTS на GPIO1 в виде 1 тоже теряется...

Мой код:
Спойлер
Код:
#include <iostm8l151g6.h>
#include <intrinsics.h> //Здесь описана функция __enable_interrupt ().

#include <d:/SI4463/san_radio_config_Si4463.h>
const unsigned char config_array[] = RADIO_CONFIGURATION_DATA_ARRAY;

// Формирование задержек
void delay(unsigned int n) {
  while (n-- > 0);
}

void si4463_nSEL_Low(void) {
  unsigned char r;
 
  r = SPI1_DR;          // clear MISO buffer
  PB_ODR_bit.ODR4 = 0;  // nSEL(SI4463) = NSS(STM8L) = low
  delay(5440);          // 340 µs
  __disable_interrupt();        // disable interrupts
}

void si4463_nSEL_High(void) {
  __enable_interrupt();         // re-enable interrupts
  while (SPI1_SR_bit.BSY){}     // wait not busy
  PB_ODR_bit.ODR4 = 1;          // nSEL(SI4463) = NSS(STM8L) = High
  delay(5440);          // 340 µs
}

// Запись байта в регистр SPI и чтение (для тактирования)
unsigned char si4463_spi_shift_byte(unsigned char tx) {
  while(!SPI1_SR_bit.TXE){}
  SPI1_DR = tx;
  while (!SPI1_SR_bit.RXNE){}
  return SPI1_DR;
}

// Посылка данных по SPI (несколько байт)
void si4463_send_config_line(unsigned char* buf, unsigned char size) {
  unsigned char i;
  si4463_nSEL_Low();
  i=0;
  while (i < size) {
    si4463_spi_shift_byte(buf[i]);
    i++;
  }
  si4463_nSEL_High();
}

// Разбор массива конфигурации трансивера и передача
unsigned int si4463_configure(const unsigned char *cmd){
  unsigned char cmd_and_param[16], size, i;
  while(*cmd != 0) {
    size = *cmd;
    cmd++;
    for(i=0; i<size; i++) {
      cmd_and_param[i]=*cmd;
      cmd++;
    }
    si4463_send_config_line(cmd_and_param, size);
  }
  return 1;
}

// Приём данных от трансивера (после команды)
unsigned int si4463_cmd_response(char* buf, unsigned int size, unsigned short int maxReq) {
  unsigned int i;
  while(maxReq > 0) {
    si4463_nSEL_Low();
    i = 0;
   
    while (i < (size + 2)) {
      if(i == 0) {
        // Первым делом посылаем команду "read CTS and the command response".
        buf[0] = si4463_spi_shift_byte(0x44);
      } else if (i == 1) {
        delay(1600);          // 100 µs
        if(si4463_spi_shift_byte(0xFF) != 0xFF) {
          // Если вернулся не 0xFF (не CTS), то повтор запроса
          maxReq--;
          break;
        }
      } else {
        // Принимаем ответ и складываем в буфер (помним, что первые два запроса были "накладными расходами")
        buf[i-2] = si4463_spi_shift_byte(0xFF);
      }
      i++;
    }
   
    si4463_nSEL_High();
    if (i > 1) {
      return 1; // Данные в буфере
    }
  }
  return 0; // Не дождались CTS
}

int main() {
  unsigned char buf[64];
  short int i;
 
  // Делитель частоты = 1, работаем 16MHz
  CLK_CKDIVR = 0;
 
  // Переназначение USART порта на альтернативные выводы (у нас так распаяно) - USART1_TX on PA2 and USART1_RX on PA3
  SYSCFG_RMPCR1_bit.USART1TR_REMAP = 1;
 
  // Переназначение тактирования USART (по умолчанию это нога висит на GPIO SI4463, а оно нам надо?) - USART1_CK mapped on PA0
  SYSCFG_RMPCR1_bit.USART1CK_REMAP = 1;
 
  // Включаем тактирование модуля USART1
  CLK_PCKENR1_bit.PCKEN15 = 1;

  // Setup USART GPIO
  PA_DDR_bit.DDR2 = 1;  // PA2 назначаем на выход: TXD
  PA_CR1_bit.C12 = 1;   // PA2 режим выхода Push-pull
  PA_CR2_bit.C22 = 1;   // PA2 output speed 10MHz
 
  PA_DDR_bit.DDR3 = 0;  // PA3 назначаем на вход: RXD
  PA_CR1_bit.C13 = 1;   // PA3 Input with pull-up
  PA_CR2_bit.C23 = 0;   // PA3 External interrupt disabled
 
  // Скорость USART 19200bps при скорости 16MHz на чипе
  USART1_BRR2 = 0x01;
  USART1_BRR1 = 0x34;
 
  // Выставляем режим: 8 бит, 1 стопбит, без контроля передачи
  USART1_CR1 = 0;
  USART1_CR3 = 0;
 
  // Режим работы USART
  USART1_CR2_bit.REN=1; // прием (хотя и не нужен в дальнейшем)
  USART1_CR2_bit.TEN=1; // передача
 
  // Включаем тактирование модуля SPI1
  CLK_PCKENR1_bit.PCKEN14 = 1;
 
  // SPI pin maps
  SYSCFG_RMPCR1_bit.SPI1_REMAP = 0;
  /*
  SPI1_MIS0 is mapped on PB7
  SPI1_MOSI is mapped on PB6
  SPI1_SCK is mapped on PB5
  SPI1_NSS is mapped on PB4
  */
 
  // SPI init
  //SPI1_ICR = 0x03; // disable interups, enable DMA
  SPI1_CR1 = 0x1C; //0x04; // SPI off, master mode, CLK/2, CPOL=CPHA=0, MSB first
  SPI1_CR2 = 0x03;      //0x03; // soft NSS, full duplex, no CRC
  SPI1_CR1 = 0x5C; //0x44; // enable SPI
 
  // setup SPI GPIOs
  PB_DDR_bit.DDR4 = 1;  // PB4 назначаем на выход: NSS
  PB_CR1_bit.C14 = 1;   // PB4 режим выхода Push-pull
  PB_CR2_bit.C24 = 1;   // PB4 output speed 10MHz
 
  PB_DDR_bit.DDR5 = 1;  // PB5 назначаем на выход: SCK
  PB_CR1_bit.C15 = 1;   // PB5 режим выхода Push-pull
  PB_CR2_bit.C25 = 1;   // PB5 output speed 10MHz
 
  PB_DDR_bit.DDR6 = 1;  // PB6 назначаем на выход: MOSI
  PB_CR1_bit.C16 = 1;   // PB6 режим выхода Push-pull
  PB_CR2_bit.C26 = 1;   // PB6 output speed 10MHz
 
  PB_DDR_bit.DDR7 = 0;  // PB7 назначаем на выход: MISO
  PB_CR1_bit.C17 = 1;   // PB7 Input with pull-up
  PB_CR2_bit.C27 = 0;   // PB7 External interrupt disabled
 
  // setup SI4463 pins & GPIO
  PB_DDR_bit.DDR3 = 1;  // PB3 назначаем на выход: SDN
  PB_CR1_bit.C13 = 1;   // PB3 режим выхода Push-pull
  PB_CR2_bit.C23 = 1;   // PB3 output speed 10MHz
 
  PC_DDR_bit.DDR0 = 0;  // PC0 назначаем на выход: NIRQ
  PC_CR1_bit.C10 = 1;   // PC0 Input with pull-up
  PC_CR2_bit.C20 = 0;   // PC0 External interrupt disabled
 
  PC_DDR_bit.DDR1 = 0;  // PC1 назначаем на выход: GPOI1
  PC_CR1_bit.C11 = 1;   // PC1 Input with pull-up
  PC_CR2_bit.C21 = 0;   // PC1 External interrupt disabled
 
  PC_DDR_bit.DDR4 = 0;  // PC4 назначаем на выход: GPIO0
  PC_CR1_bit.C14 = 1;   // PC4 Input with pull-up
  PC_CR2_bit.C24 = 0;   // PC4 External interrupt disabled
 
 
  // Enable 26MHz oscillator
  PB_DDR_bit.DDR2 = 1;  // PB2 назначаем на выход
  PB_CR1_bit.C12 = 1;   // PB2 режим выхода Push-pull
  PB_CR2_bit.C22 = 1;   // PB2 output speed 10MHz
  PB_ODR_bit.ODR2 = 1;  // Enable
 
 
  // Shutdown\Reset SI4463
  PB_ODR_bit.ODR4 = 1;  // NSS = High;
  PB_ODR_bit.ODR3 = 1;  // SDN = 1 = Shutdown
  delay(240000);        // 15ms
 
  PB_ODR_bit.ODR3 = 0;  // SDN = 0
 
  while (!PC_IDR_bit.IDR1) {}   // wait CTS on GPIO1(SI4463) = PC1(STM8L)
  //si4463_configure(config_array);
 
  /*
  // SI4463 POWER_UP
  buf[0]=0x02;
  buf[1]=0x01;
  buf[2]=0x00;
  // 26MHz
  buf[3]=0x01;
  buf[4]=0x8C;
  buf[5]=0xBA;
  buf[6]=0x80;
  si4463_send_config_line(buf, 7);
  */
  while (1) {
 
    // SI4463 query
  buf[0]=0x01;  // PART_INFO
  si4463_send_config_line(buf, 1);
 
  if ( si4463_cmd_response(buf, 8, 10)==1 ) {
  for (i=0; i<8; i++) {
      while (!USART1_SR_bit.TXE) {}
      USART1_DR = buf[i];
    }
  }
 
  }
  /*
  while (1) {
    buf[0]=0x14;        //  GET_ADC_READING
    buf[0]=0x18;        // Temperature & Battery
    si4463_send_config_line(buf, 2);
    if ( si4463_cmd_response(buf, 9, 10)==1 ) {
      for (i=0; i<9; i++) {
        while (!USART1_SR_bit.TXE) {}
        USART1_DR = buf[i];
      }
    }
    delay(16000000);
  }
  */
}



ЗЫ: Алгоритм инициализации откровенно слизан с примеров WDM3.

Re: Si4463 не взлетает

Ср янв 16, 2019 17:49:33

Выложите осциллограммы лог. анализатора SPI коммуникации с чипом включая CTS.

Re: Si4463 не взлетает

Ср янв 23, 2019 11:47:41

К сожалению пайка такова, что подключить лог-анализатор не вышло :(
Как выяснилось в коде и подключении проблем нет. В данном случае ситуация такова: если выполняя команду POWER_UP, вторым байтом идет не 1, а 0, то микруха начинает вести себя адекватно, выдавая CTS. Этот байт в документации интерпретируется 1 - Boot main application image, 0 - Stay on bootload.
Собственно вопросы: что за bootload (пока не нашёл инфы), как исправить (т.к. после конфигурирования все равно не фунцикляет :( )???
Изображение

Re: Si4463 не взлетает

Ср янв 23, 2019 23:17:06

Хмммм. У меня в документации на ревизию В написано, что опция FUNC=1 единственная для перевода чипа в режим PRO.
Я всегда посылал следующую последовательность байтов для POWERUP:
0x02 0x01 0x00 0x01 0xC9 0xC3 0x80
где последние 4 байта - это частота кварца (01C9C380 = 30.000.000 гц = 30 мгц).
Правда, китайские платы никогда не использовал.
powerup.png
(18.38 KiB) Скачиваний: 405

Re: Si4463 не взлетает

Ср фев 13, 2019 17:52:55

Выяснилось, проблема в железе... И ещё в этом модуле кварц 26МГц стартует не с вывода XOUT SI4464, а с вывода управляющей STM8, также в команде POWER_UP необходимо включить XTAL_OPTIONS TCXO иначе не работает.

Написан код передатчика, загружен в один из модулей, нахожусь в полной уверенности что он что-то передаёт - радиостанция характерно шипит на этой частоте.
Но вот с приёмником не справился :( Прерывание по приёму поступают хаотично и в FIFO валит мусор при этом в эфире чисто.
Скрины WDS:
Изображение
Изображение

Пояснения к коду: процедура spi_send_buf по всем правилам отправляет из буфера обозначенное кол-во байт, si4463_get_response по всем правилам принимает от si4463 ответ, второй параметр сколько байт принять, третий - кол-во попыток в случае с задержкой CTS. На выводе PC0 висит nIRQ.
Кусок кода:
Спойлер
Код:
/* SI4463 READY */
 
  buf[0]=0x01; spi_send_buf(buf, 1); // PART_INFO
  if (si4463_get_response(buf, 8, 3) != 0) {
    buf[8]=0x0A;
    send2usart(buf, 9);
  }
 
  buf[0]=0x32;  // START_RX
  buf[1]=0;     // Channel
  buf[2]=0;     // Start RX immediately.
  buf[3]=0;     // RX_LEN HW
  buf[4]=24;    // RX_LEN LW
  buf[5]=0;     // RXTIMEOUT_STATE 0=NOCHANGE
  buf[6]=3;     // RXVALID_STATE 8=RX state (briefly exit and re-enter RX state to re-arm for acquisition of another packet).
  buf[7]=3;     // RXINVALID_STATE 6=RX_TUNE state.
  waitCTS();
  spi_send_buf(buf, 8);
  waitCTS();
 
  PC_CR2_bit.C20 = 1;    // nIRQ External interrupt enable
  EXTI_CR1_bit.P0IS = 2; // 10b
  CPU_CFG_GCR_bit.AL = 1;
  asm("RIM");
  asm("HALT");
}

#pragma vector=EXTI0_vector
__interrupt void packet_received(void){
  unsigned char rx;
 
  buf[0]=0x15;  // FIFO_INFO
  buf[1]=0;     // not reset
  waitCTS();
  spi_send_buf(buf, 2);
  if (si4463_get_response(buf, 2, 3) != 0) {
    rx=buf[0];
    buf[2]=0xFF;
    send2usart(buf, 3); // 2USART
  }
 
  if (rx!=0){
    buf[0]=0x77;        // READ_FIFO
    spi_send_buf(buf, 1);
    si4463_get_response(buf, rx, 3);
    buf[rx]=0x0A;
    send2usart(buf, rx+1);      // 2USART
  }
 
  buf[0]=0x15;  // FIFO_INFO
  buf[1]=3;     // reset RX and TX
  waitCTS();
  spi_send_buf(buf, 2);
  si4463_get_response(buf, 2, 3);
 
  buf[0]=0x20;  // GET_INT_STATUS
  buf[1]=0;
  buf[2]=0;
  buf[3]=0;
  waitCTS();
  spi_send_buf(buf, 4);
  si4463_get_response(buf, 8, 3);
 
  buf[0]=0x32;  // START_RX
  buf[1]=0;     // Channel
  buf[2]=0;     // Start RX immediately.
  buf[3]=0;     // RX_LEN HW
  buf[4]=24;    // RX_LEN LW
  buf[5]=0;     // RXTIMEOUT_STATE
  buf[6]=3;     // RXVALID_STATE
  buf[7]=3;     // RXINVALID_STATE
  waitCTS();
  spi_send_buf(buf, 8);
  waitCTS();
 
  EXTI_SR1_bit.P0F = 1; //escape from interrupt
}



Не знаю куда копать... :dont_know:

Re: Si4463 не взлетает

Ср фев 13, 2019 18:13:56

logind писал(а):Прерывание по приёму поступают хаотично и в FIFO валит мусор при этом в эфире чисто.

в эфире не бувает пусто)) при отсутствии сигнала присутствует шум эфира.

шум эфира подробно разбирали на примере радиомодуля nRF24L01 - https://radiokot.ru/forum/viewtopic.php?f=61&t=156225

все эти модули по сути работают одинаково... кроме специальных, со своими протоколами... типа Lora и т.д.

Re: Si4463 не взлетает

Ср фев 13, 2019 20:10:19

Это я понимаю. Но мы же пытаемся принять пакет с определенной преамбулой и синхрословом... Конкретно в моём случае, я загружаю следующий конфиг, как в приёмник, так и в передатчик:
Спойлер
Код:
/*
// Set properties:           RF_PREAMBLE_TX_LENGTH_9
// Number of properties:     9
// Group ID:                 0x10
// Start ID:                 0x00
// Default values:           0x08, 0x14, 0x00, 0x0F, 0x21, 0x00, 0x00, 0x00, 0x00,
// Descriptions:
//   PREAMBLE_TX_LENGTH - Configure length of TX Preamble.
//   PREAMBLE_CONFIG_STD_1 - Configuration of reception of a packet with a Standard Preamble pattern.
//   PREAMBLE_CONFIG_NSTD - Configuration of transmission/reception of a packet with a Non-Standard Preamble pattern.
//   PREAMBLE_CONFIG_STD_2 - Configuration of timeout periods during reception of a packet with Standard Preamble pattern.
//   PREAMBLE_CONFIG - General configuration bits for the Preamble field.
//   PREAMBLE_PATTERN_31_24 - Configuration of the bit values describing a Non-Standard Preamble pattern.
//   PREAMBLE_PATTERN_23_16 - Configuration of the bit values describing a Non-Standard Preamble pattern.
//   PREAMBLE_PATTERN_15_8 - Configuration of the bit values describing a Non-Standard Preamble pattern.
//   PREAMBLE_PATTERN_7_0 - Configuration of the bit values describing a Non-Standard Preamble pattern.
*/
#define RF_PREAMBLE_TX_LENGTH_9 0x11, 0x10, 0x09, 0x00, 0x08, 0x18, 0xF7, 0x0F, 0x30, 0x00, 0x33, 0x33, 0x33

/*
// Set properties:           RF_SYNC_CONFIG_5
// Number of properties:     5
// Group ID:                 0x11
// Start ID:                 0x00
// Default values:           0x01, 0x2D, 0xD4, 0x2D, 0xD4,
// Descriptions:
//   SYNC_CONFIG - Sync Word configuration bits.
//   SYNC_BITS_31_24 - Sync word.
//   SYNC_BITS_23_16 - Sync word.
//   SYNC_BITS_15_8 - Sync word.
//   SYNC_BITS_7_0 - Sync word.
*/
#define RF_SYNC_CONFIG_5 0x11, 0x11, 0x05, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00



Кстати пакет который передается передатчиком (другим модулем), в нужном формате, я не принимаю :(

Re: Si4463 не взлетает

Чт фев 14, 2019 22:02:09

Хорошо-бы посмотреть коды Ваших функций spi_send_buf() и si4463_get_response(). Зря Вы делаете всю обработку в ISR. Это следует делать в main().
Перевод чипа в режим приёме происходит не мгновенно. Следует читать статус чипа до тех пор пока он не укажет состояние приёма. И только потом гасить флаги прерывания в чипе.
Вот пример как это сделано у меня для чипа Si4362 - для Si4463 аналогично. Аргументы функций - это массивы байтов для соответствующих команд. Например,
const uint8_t SI4362_start_rx[] = {0x08, 0x32, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08}; // START_RX
где первый байт у меня - это длина массива.
Код:
do   
   {
      SI4362_write(SI4362_rqst_device_state);         // Send REQUEST_DEVICE_STATE command
      SI4362_read(SI4362_read_cmd_buff, 3);         // Send READ_CMD_BUFF command
   } while (SPIbuf[1] != 0x08);                  // loop that waits for RX state
   SI4362_write(SI4362_clear_irq);                  // Send CLEAR_IRQ command


Ещё неясно зачем ограничивать число попыток чтения инфы из чипа в si4463_get_response()? Почему просто не дождаться CTS Вашей функцией waitCTS() и потом уже производить приём наверняка. Также, зачем вызываете waitCTS() после spi_send_buf() в некольких местах. Это не ошибка, но зачем?

Re: Si4463 не взлетает

Пт фев 15, 2019 08:38:07

К сожалению не могу отредактировать свой предыдущий пост :(
Решил выложить всю информацию о модуле E30-170T20D, вдруг кому пригодится и поможет разобраться в моём косяке.
Фото:
СпойлерИзображение
Изображение


Схема коммутации MCU & SI446:
Изображение

Скрины настройки в WDS:
СпойлерИзображение
Без подчёркнутой галки SI4463 после POWER_UP не выдаёт CTS
Изображение
Изображение
Изображение
В поле field видно, что полезны 24 байта.
Изображение
Изображение


При таком же загруженном конфиге в передатчик, на радиостанции на указанной частоте слышу характерный звук с паузой между пакетами, которую я использую при передаче - делаю вывод, что передаёт :)

Код приёмника (IAR):
Спойлер
Код:
#include <iostm8l151g6.h>

#include <d:/SI4463/rx-radio_config_Si4463.h>
const unsigned char config_array[] = RADIO_CONFIGURATION_DATA_ARRAY;

unsigned char buf[64];

void delay_us( unsigned int us ) {
  unsigned int t = (unsigned int)(3.2*us);        // while(t>0){t--;} 4-5 tacts 16/5=3.2
 
  while (t>0) {
    t--;
  }
}

void delay_ms( unsigned int ms ) {
  while (ms>0) {
    delay_us(1000);
    ms--;
  }
}

void delay( unsigned int s ) {
  while (s>0) {
    delay_ms(1000);
    s--;
  } 
}

void send2usart( unsigned char *buf, unsigned char len ){
  for (unsigned char i=0; i<len; i++){
    while (!USART1_SR_bit.TXE) {
      asm("nop");
    }
    USART1_DR = buf[i];
  }
}

unsigned char spi_shift_byte( unsigned char tx ) {
  while (!SPI1_SR_bit.TXE) {
    asm("nop");
  }
  SPI1_DR = tx;
  while (!SPI1_SR_bit.RXNE) {
    asm("nop");
  }
  return SPI1_DR;
}

void spi_start( void ){
  PB_ODR_bit.ODR4 = 0;  // SI4463 nSEL low level for SPI_CR2_bit.SSM = 1
  SPI1_CR1_bit.SPE = 1; // Enable SPI
  delay_us(20);         // 20µs
}

void spi_end( void ){
  while (SPI1_SR_bit.BSY) {
    asm("nop");
  }
  PB_ODR_bit.ODR4 = 1;  // SI4463 nSEL high level for SPI_CR2_bit.SSM = 1
  SPI1_CR1_bit.SPE = 0; // Disable SPI
  delay_us(80);         // 80µs
}
/*
void waitCTSspi ( void ){
  unsigned char rx=0;
 
  while (rx!=0xFF) {
    spi_start();
    rx = spi_shift_byte(0x44);
    rx = spi_shift_byte(0xFF);
    spi_end();
  }
}
*/
// wait CTC (HIGH) on GPIO1(SI4463) = PC1(STM8L)
void waitCTS( void ) {
  while ( !PC_IDR_bit.IDR1 ){
    asm("nop");
  }
}

void spi_send_buf(unsigned char* buf, unsigned char len) {
  unsigned char i;
 
  spi_start();
  for (i=0; i<len; i++){
    spi_shift_byte(buf[i]);
  }
  spi_end();
}

void parse_config_si4463(const unsigned char *cmd){
  unsigned char cmd_and_param[16], size, i;
 
  while( *cmd != 0 ) {
    size = *cmd;
    cmd++;
    for(i=0; i<size; i++) {
      cmd_and_param[i]=*cmd;
      cmd++;
    }
    waitCTS();
    spi_send_buf(cmd_and_param, size);
  }
}

unsigned char si4463_get_response( unsigned char *buf, unsigned char len, unsigned char maxReq ) {
  unsigned char i;
 
  while (maxReq > 0) {
    i=0;
    spi_start();
    if (i==0) {
      spi_shift_byte(0x44);
      if ( spi_shift_byte(0xFF) != 0xFF ) {
        maxReq--;
      } else {
        for (i=0; i<len; i++) {
          buf[i] = spi_shift_byte(0xFF);
        }
        maxReq=0;
      }
    }
    spi_end();
  }
  return i;
}

void main( void ) {
  CLK_CKDIVR = 0;       // 16 MHz HSI clock
 
  // Used pin setup
  PA_DDR_bit.DDR2 = 1;  // output MODULE TXD
  PA_CR1_bit.C12 = 1;   // Push-pull
  PA_CR2_bit.C22 = 1;   // Output speed up to 10 MHz
 
  PA_DDR_bit.DDR3 = 0;  // input MODULE RXD
  PA_CR1_bit.C13 = 1;   // Input with pull-up
  PA_CR2_bit.C23 = 0;   // External interrupt disabled
 
  PB_DDR_bit.DDR2 = 1;  // output SI4463 OSCILATOR
  PB_CR1_bit.C12 = 1;   // Push-pull
  PB_CR2_bit.C22 = 1;   // Output speed up to 10 MHz
 
  PB_DDR_bit.DDR3 = 1;  // output SI4463 SDN
  PB_CR1_bit.C13 = 1;   // Push-pull
  PB_CR2_bit.C23 = 1;   // Output speed up to 10 MHz
 
  PB_DDR_bit.DDR4 = 1;  // output SI4463 nSEL
  PB_CR1_bit.C14 = 1;   // Push-pull
  PB_CR2_bit.C24 = 1;   // Output speed up to 10 MHz
 
  PB_DDR_bit.DDR5 = 1;  // output SI4463 SCLK
  PB_CR1_bit.C15 = 1;   // Push-pull
  PB_CR2_bit.C25 = 1;   // Output speed up to 10 MHz
 
  PB_DDR_bit.DDR6 = 1;  // output SI4463 SDI
  PB_CR1_bit.C16 = 1;   // Push-pull
  PB_CR2_bit.C26 = 1;   // Output speed up to 10 MHz
 
  PB_DDR_bit.DDR7 = 0;  // input SI4463 SDO
  PB_CR1_bit.C17 = 1;   // Input with pull-up
  PB_CR2_bit.C27 = 0;   // External interrupt disabled
 
  PC_DDR_bit.DDR0 = 0;  // input SI4463 nIRQ
  PC_CR1_bit.C10 = 1;   // Input with pull-up
  PC_CR2_bit.C20 = 0;   // External interrupt disabled
 
  PC_DDR_bit.DDR1 = 0;  // input SI4463 GPIO1
  PC_CR1_bit.C11 = 1;   // Input with pull-up
  PC_CR2_bit.C21 = 0;   // External interrupt disabled
 
  PC_DDR_bit.DDR4 = 0;  // input SI4463 GPIO0
  PC_CR1_bit.C14 = 1;   // Input with pull-up
  PC_CR2_bit.C24 = 0;   // External interrupt disabled
 
  PC_DDR_bit.DDR5 = 1;  // output MODULE M0
  PC_CR1_bit.C15 = 1;   // Push-pull
  PC_CR2_bit.C25 = 1;   // Output speed up to 10 MHz
 
  PC_DDR_bit.DDR6 = 1;  // output MODULE M1
  PC_CR1_bit.C16 = 1;   // Push-pull
  PC_CR2_bit.C26 = 1;   // Output speed up to 10 MHz
 
  PD_DDR_bit.DDR0 = 1;  // output MODULE AUX
  PD_CR1_bit.C10 = 1;   // Push-pull
  PD_CR2_bit.C20 = 1;   // Output speed up to 10 MHz
 
  // Not used pin output
  PA_DDR_bit.DDR0 = 1; PA_CR1_bit.C10 = 1; //PA_ODR_bit.ODR0 = 1;
  PA_DDR_bit.DDR1 = 1; PA_CR1_bit.C11 = 1; //PA_ODR_bit.ODR1 = 1;
  PA_DDR_bit.DDR4 = 1; PA_CR1_bit.C14 = 1; //PA_ODR_bit.ODR4 = 1;
  PA_DDR_bit.DDR5 = 1; PA_CR1_bit.C15 = 1; //PA_ODR_bit.ODR5 = 1;
  PB_DDR_bit.DDR0 = 1; PB_CR1_bit.C10 = 1; //PB_ODR_bit.ODR0 = 1;
  PB_DDR_bit.DDR1 = 1; PB_CR1_bit.C11 = 1; //PB_ODR_bit.ODR1 = 1;
  PC_DDR_bit.DDR2 = 1; PC_CR1_bit.C12 = 1; //PC_ODR_bit.ODR2 = 1;
  PC_DDR_bit.DDR3 = 1; PC_CR1_bit.C13 = 1; //PC_ODR_bit.ODR3 = 1;
  PD_DDR_bit.DDR1 = 1; PD_CR1_bit.C11 = 1; //PD_ODR_bit.ODR1 = 1;
  PD_DDR_bit.DDR2 = 1; PD_CR1_bit.C12 = 1; //PD_ODR_bit.ODR2 = 1;
  PD_DDR_bit.DDR3 = 1; PD_CR1_bit.C13 = 1; //PD_ODR_bit.ODR3 = 1;

 
  // USART Configure
  CLK_PCKENR1_bit.PCKEN15 = 1;  // STM8L enable tacting USART
  // Remap USART pin
  SYSCFG_RMPCR1_bit.USART1TR_REMAP = 1; // USART1_TX on PA2 and USART1_RX on PA3
  SYSCFG_RMPCR1_bit.USART1CK_REMAP = 1; // USART1_CK mapped on PA0
  // USART Speed 19200bps for 16MHz clock on chip
  USART1_BRR2 = 0x01;
  USART1_BRR1 = 0x34;
  // USART 8-N-1
  USART1_CR1 = 0;
  USART1_CR3 = 0;
  // USART pin
  USART1_CR2_bit.REN = 0; // RX disable
  USART1_CR2_bit.TEN = 1; // TX enable
 
 
  // SPI Configure
  PB_ODR_bit.ODR4 = 1;          // SI4463 nSEL default high level
  CLK_PCKENR1_bit.PCKEN14 = 1;  // STM8L enable tacting SPI
 
  SPI1_ICR = 0x00; // Disable interups, disable DMA
  SPI1_CR1 = 0x04; // LSBFIRST=0, SPE=0, BR=000b, MSTR=1, CPOL=0, CPHA=0
                   // MSB is transmitted first, SPI disabled, Baud rate control fSYSCLK/2, Master configuration, SCK to 0 when idle, The first clock transition is the first data capture edge
  SPI1_CR2 = 0x03; // BDM=0, BDOE=0, CRCEN=0, CRCNEXT=0, RXONLY=0, SSM=1, SSI=1
                   // 2-line unidirectional data mode selected, Full duplex, Software slave management enabled,  Master mode
 
  // SI4463 reset
  PB_ODR_bit.ODR2 = 1;  // Enable 26MHz Crystal Oscillator for SI4463 (XIN pin)
  PB_ODR_bit.ODR3 = 1;  // Shutdown SI4463 (SDN pin high)
  delay_us(10);         // 10us <- AN633 p25 
  PB_ODR_bit.ODR3 = 0;  // PowerUp SI4463 (SDN pin low)
  //delay_ms(6);          // 6ms <- AN633 p25
  waitCTS();
 
  // parse including config and send to SI4463
  parse_config_si4463(config_array);
 
  buf[0]=0x20;  // GET_INT_STATUS
  buf[1]=0;
  buf[2]=0;
  buf[3]=0;
  waitCTS();
  spi_send_buf(buf, 4);
  si4463_get_response(buf, 8, 3);

  /* SI4463 READY */
 
  buf[0]=0x01; spi_send_buf(buf, 1); // PART_INFO
  if (si4463_get_response(buf, 8, 3) != 0) {
    buf[8]=0x0A;
    send2usart(buf, 9);
  }
 
  buf[0]=0x32;  // START_RX
  buf[1]=0;     // Channel
  buf[2]=0;     // Start RX immediately.
  buf[3]=0;     // RX_LEN HW
  buf[4]=24;    // RX_LEN LW
  buf[5]=0;     // RXTIMEOUT_STATE 0=NOCHANGE
  buf[6]=3;     // RXVALID_STATE 8=RX state (briefly exit and re-enter RX state to re-arm for acquisition of another packet).
  buf[7]=3;     // RXINVALID_STATE 6=RX_TUNE state.
  waitCTS();
  spi_send_buf(buf, 8);
  waitCTS();
 
  PC_CR2_bit.C20 = 1;    // nIRQ External interrupt enable
  EXTI_CR1_bit.P0IS = 2; // 10b
  CPU_CFG_GCR_bit.AL = 1;
  asm("RIM");
  //asm("HALT");
  while (1){
    asm("WFI");
  }
}

#pragma vector=EXTI0_vector
__interrupt void packet_received(void){
  unsigned char rx;
 
  buf[0]=0x15;  // FIFO_INFO
  buf[1]=0;     // not reset
  waitCTS();
  spi_send_buf(buf, 2);
  if (si4463_get_response(buf, 2, 3) != 0) {
    rx=buf[0];
    buf[2]=0xFF;
    send2usart(buf, 3); // 2USART
  }
 
  if (rx!=0){
    buf[0]=0x77;        // READ_FIFO
    spi_send_buf(buf, 1);
    si4463_get_response(buf, rx, 3);
    buf[rx]=0x0A;
    send2usart(buf, rx+1);      // 2USART
  }
 
  buf[0]=0x15;  // FIFO_INFO
  buf[1]=3;     // reset RX and TX
  waitCTS();
  spi_send_buf(buf, 2);
  si4463_get_response(buf, 2, 3);
 
  buf[0]=0x20;  // GET_INT_STATUS
  buf[1]=0;
  buf[2]=0;
  buf[3]=0;
  waitCTS();
  spi_send_buf(buf, 4);
  si4463_get_response(buf, 8, 3);
 
  buf[0]=0x32;  // START_RX
  buf[1]=0;     // Channel
  buf[2]=0;     // Start RX immediately.
  buf[3]=0;     // RX_LEN HW
  buf[4]=24;    // RX_LEN LW
  buf[5]=0;     // RXTIMEOUT_STATE
  buf[6]=3;     // RXVALID_STATE
  buf[7]=3;     // RXINVALID_STATE
  waitCTS();
  spi_send_buf(buf, 8);
  waitCTS();
 
  EXTI_SR1_bit.P0F = 1; //escape from interrupt
}

Код:
Результат работы кода приёмника:
11 44 63 0 0 F 0 3
18 40 FF 18 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 40 0 0 0 0 0 0
18 40 FF 18 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 40 0 0 0 0 0 0
18 40 FF 18 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 40 0 0 0 0 0 0
18 40 FF 18 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 40 0 0 0 0 0 0

В общем, первая строка, результат PART_INFO. Следующие строки: 2-а байта RX FIFO, и TX FIFO, 0xFF разделитель, 0x18 = 24 данные из RX FIFO.
Данные приходят 2-3 раза в секунду... Откуда не знаю :)
Передаю я 1-н пакет в ~3 сек, патерн 24 байта. Пакет, который передаётся моим передатчиком, не принимается :(

Ser60: К сожалению дополнительная проверка REQUEST_DEVICE_STATE не дала ясности, трансивер всегда отвечает байтами 8, 0. Т.е.: RX state, CURRENT_CHANNEL: 0.
В команде START_RX параметры NEXT_STATE выставлял 8-ки, изменений нет.

По поводу ограничения попыток - предполагаю, что в некоторых случаях придётся ресетится... Привык я так писать :)

Re: Si4463 не взлетает

Пт фев 15, 2019 16:16:46

Попробуйте после приёма первого пакета отключить передатчик. Если по-прежнему будет приниматься тот-же пакет, то дело явно в приёмнике. После чтения пакета из Fifo попробуйте clear Fifo и послать в приёмник код сброса флагов прерывания до перехода к приёму нового пакета. Дайте знать что получится. Может это Вы и делаете уже, я сейчас подробно код не смотрел.

Re: Si4463 не взлетает

Пн фев 18, 2019 17:19:43

Всем привет!

У меня как у logind получается:
Код:
FF 12 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 40
FF 24 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 24 40
FF 36 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 40
FF 3C 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3C 40
FF 0D 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0D 40


Это содержание RX_FIFO.
Передатчик Si4012, приемник Si4463, 169.4MГц, ООК, 32kbps.
Все настройки Si4463 из WDS.
Преамбюл 4 байта 0xAA, синхрослово 2 байта 0x2D 0xD4 (0xB4 0x2B в настройки приемника), одно поле (18 байт) для данных.
GPIO_1 = CTS, GPIO_3 = VALID_PREAMBLE, IRQ = VALID_SYNC
Получаю преамбюл и синхрослово (GPIO_3 = VALID_PREAMBLE и IRQ = VALID_SYNC переходят из 0 в 1 и наоборот, но ничего больше этого.

Статьи Ser60 читал.

P.S. Извините за русский. Я болгар и русский учил где-то сорока лет назад...

Re: Si4463 не взлетает

Пн фев 18, 2019 18:18:07

Коля, неясно зачем Вам нужно IRQ = VALID_SYNC? Я всегда ставлю IRQ=0x27 и прерывание определяется битами в WDS конфирурации. В противном случае если читаете FIFO сразу после принятия синхрослова, то приём пакета в этот момент может быть не завершено, особенно если читаете из FIFO быстрее чем принимаются данные. Также рекомендую обнулять RX FIFO каждый раз перед принятием нового пакета (из Вашего сообщение неясно делается-ли это).

Re: Si4463 не взлетает

Вт фев 19, 2019 13:21:15

SYNC_WORD_DETECT 26 This output goes high when a Sync Word is detected, and returns low after the packet is received.

Конечно, FIFO обнуляется.

Re: Si4463 не взлетает

Вт фев 19, 2019 16:06:19

Можете привести фрагмент кода где ожидаете приём пакета и чтения его из FIFO в приёмнике и код передачи пакета в передатчике? А также осциллограммы на выводах SPI включая CTS. Ну и, наконец, конгигурацию регистров приёмника и передатчика.

Re: Si4463 не взлетает

Вт фев 19, 2019 17:20:52

Нашел ошибку!!! Команду READ_RX_FIFO (WRITE_TX_FIFO тоже), должно посылать как READ_FRR_X комманд:
Код:
output_low(PIN_SI4463_CS);
spi_write(0x77);   
for (byte_cnt = 0; byte_cnt < rx_bytes; byte_cnt ++)
{
   g_Si4463_Rx_Buffer[byte_cnt] = spi_read(0);
}
output_high(PIN_SI4463_CS);

Спасибо за поддержку Ser60!
А можно еще спросить о том какая модуляция и ее параметры лучше выбрать для достижения максимальной дистанции?
Ответить