Помогите разобраться с автоподтверждением на rfm70

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Родился
Сообщения: 1
Зарегистрирован: Сб сен 29, 2012 22:35:51

Сообщение necroman »

Всем доброго времени суток...
Столкнулся с проблемой, которую вот уже 4 дня никак не могу решить... Не получается настроить автоматическое подтверждение прием(ACK). Гугл поиск та и не дал нужные ответы...
Передатчик передает сообщение, приемник получает(видно по светодиоду), но не отправляет подтверждения, поэтому передатчик пытается отправить еще и еще... Соответственно передатчик отправляет n-ое(настраивал разное количество с разным интервалом) количество пакетов и выдает сообщение(STATUS) о максимальном количестве попыток... А приемник, соответственно, получает столько же посылок, но при этом не отправляет подтверждение...

Вот код банка 0(одинаковый для приемника и передатчика):
Спойлер

Код: Выделить всё

/************ Bank0 register initialization commands
 const uint8_t PROGMEM RFM70_bank0Init[][2] = {
  // address data
  { (0x20|0x00), 0x0F }, //Disable CRC ,CRC=1byte, POWER UP, TX
  { (0x20|0x01), 0x03 }, //Включение автоответа с RX0 по RX5
  { (0x20|0x02), 0x03 }, //Задействие RX адрессов с RX0 по RX5
  { (0x20|0x03), 0x03 }, //RX/TX address field width 5byte
  { (0x20|0x04), 0x06 }, //x = 250 ms = 4000ms, y = 15 tries
  { (0x20|0x05), 0x01 }, //channel = 0x17
  { (0x20|0x06), 0x1F }, //air data rate-2M,out power 5dbm,setup LNA gain high (0dBM)
  { (0x20|0x07), 0x70 }, //
  { (0x20|0x08), 0x00 }, //
  { (0x20|0x09), 0x00 }, //
  { (0x20|0x0C), 0xc3 }, //LSB Addr pipe 2
  { (0x20|0x0D), 0xc4 }, //LSB Addr pipe 3
  { (0x20|0x0E), 0xc5 }, //LSB Addr pipe 4
  { (0x20|0x0F), 0xc6 }, //LSB Addr pipe 5
  { (0x20|0x11), 0x20 }, //Payload len pipe0
  { (0x20|0x12), 0x20 }, //Payload len pipe0
  { (0x20|0x13), 0x20 }, //Payload len pipe0
  { (0x20|0x14), 0x20 }, //Payload len pipe0
  { (0x20|0x15), 0x20 }, //Payload len pipe0
  { (0x20|0x16), 0x20 }, //Payload len pipe0
  { (0x20|0x17), 0x11 }, //Payload len pipe0
  { (0x20|0x1C), 0x01 }, //Enable dynamic payload legth data pipe0-5
  { (0x20|0x1D), 0x04 } //Enables Dynamic Payload Length,Enables Payload with ACK
};
Передают вот так вот:
Спойлер

Код: Выделить всё

// В программе				
setMode(0);
_delay_ms(10);
uchar data[29];
sendPayload(data,29, 0x01);

uint8_t sendPayload(uint8_t * payload, uint8_t len, uint8_t toAck)	// choose 0=nAck, 1=AckRequest
{
	
  	// check TX_FIFO
  	uint8_t status;
  	status = readRegVal(RFM70_REG_FIFO_STATUS); 
  	if (status & RFM70_FIFO_STATUS_TX_FULL) 
	{
    	return 0;
  	}

  	// send payload
	PORT_SPI &=~ (1<<CSN);
  	_delay_ms(RFM70_CS_DELAY);
  	if(toAck == 0x01)
    	transmitSPI(RFM70_CMD_WR_TX_PLOAD);
  	else if (toAck == 0x00)
    	transmitSPI(RFM70_CMD_W_TX_PAYLOAD_NOACK);
  	else
    	transmitSPI(RFM70_CMD_W_ACK_PAYLOAD);
  	while(len--) 
	{
    	transmitSPI(*(payload++));
  	}
	PORT_SPI |= (1<<CSN);
  	_delay_ms(RFM70_CS_DELAY);
//	uart_puts("\n");

  	return 1;
}
Принимаю сообщение вот так:
Спойлер

Код: Выделить всё

SIGNAL ( INT0_vect )
{
		uint8_t val;
		//writeRegPgmBuf((uint8_t *)RFM70_cmd_flush_rx, sizeof(RFM70_cmd_flush_rx)); // Flush RX FIFO
		val = readRegVal(RFM70_REG_STATUS); // Read Status
		if(val & RFM70_IRQ_STATUS_RX_DR)
		{	
			PORTB ^=(1<<PB0);
			receivePayload(test1);
			//flag_prer = 0x01;
		}
		else if((val & RFM70_IRQ_STATUS_TX_DS) || (val & RFM70_IRQ_STATUS_MAX_RT))
		{
			PORTB |=(1<<PB0);
			PORTB ^=(1<<PB1);
			setMode(1);
			_delay_ms(10);
			
		}
		//val = readRegVal(RFM70_REG_STATUS); // Read Status
		writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, val); // Reset IRQ bits
}
Буду рад любым идеям и предложениям... Заранее спасибо...

P.S. конечно можно сделать программную реализацию подтверждения, но это на тот случай, если не смогу разобраться с этой проблемой...
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 47
Зарегистрирован: Чт дек 22, 2011 22:22:46
Откуда: Тольятти

Сообщение iev91 »

necroman писал(а): // send payload
PORT_SPI &=~ (1<<CSN);
_delay_ms(RFM70_CS_DELAY);
if(toAck == 0x01)
transmitSPI(RFM70_CMD_WR_TX_PLOAD);
else if (toAck == 0x00)
transmitSPI(RFM70_CMD_W_TX_PAYLOAD_NOACK);
else
transmitSPI(RFM70_CMD_W_ACK_PAYLOAD);
Если флажок toAck может принимать только два значения, то один из этих трех вариантов никогда не реализуется. Компилятор должен был на втором else выдать предупреждение Warninhg: code unreacheable.
necroman писал(а): { (0x20|0x17), 0x11 }, //Payload len pipe0
{ (0x20|0x1C), 0x01 }, //Enable dynamic payload legth data pipe0-5
{ (0x20|0x1D), 0x04 } //Enables Dynamic Payload Length,Enables Payload with ACK
Регистр 17 - это уже FIFO_STATUS.
В регистр 1D вроде бы надо поставить флажок EN_ACK_PAY, хотя там путаница от производителя.
Контактная информация:
Реклама
Ответить

Вернуться в «Периферия»