Добрый день.
Начал работу с микросхемой CYRF6936 (до этого работал с CYWUSB693*) и возникли проблеммы.
Ну для начала переход с LS на LP оказался не такой тривиальный как я думал сначала. Но это просто к слову.
По сути вопроса.
Имею две одинаковые платы (условно приемник и передатчик). Основной клок заведен от микроконтроллера (формируется аппаратно путем деленяи базовой частоты 24МГц на 2. Т.е. получаю 12 МГц) на CYRF (т.е. тактую CYRF внешним источником).
Схема включения CYRF взята из даташита (без использования внутреннего преобразователя).
Произвожу инициализацию микросхемы (код одинаковый на обоих платах) и вхожу в бесконечный цикл ожидания приема и при отсутствии данные передачу синхропакета.
И по идее должен получать установившееся соединение. По факту этого не происходит. Поставил датчик тока по питанию CYRF, для контроля работы ВЧ цепей микросхемы. Нормально наблюдаю рабоут передающей части и в нужный момент принимающей части (т.е. потребление в нужный момент меняется). Делаю вывод что микросхема работает правильно.
Но так как соединения у меня так и не получается - значит есть ошибка в программе.
Помогите пожалуйста с правильностью инициализации! И вообще правильно ли я произвожу работу с микросхемой в процедурах чтения и передачи?Может быть все же проблемма в плате? Много неизвестных, так как этот корпус распаиваем в ручную феном. Человек который распаивал уже пожег 10 микросхем. Я в шоке. Но дабы быть уверенным со своей стороны, хотел бы получить помощь по программной части.
Я произвожу инициализацию микросхемы при запуске системы следующими данными (половину настроек взял из документации, половину из примеров Cypress)
CODE
// массив инициализации
code const byte radio_init_data[] =
{
MODE_OVERRIDE_ADR,RST, // сбрасываем радио CYRF
CLK_EN_ADR,RXF, // по доке нужно сделать при инициализации
AUTO_CAL_TIME_ADR,AUTO_CAL_TIME_MAX, // по доке нужно сделать при инициализации
AUTO_CAL_OFFSET_ADR,AUTO_CAL_OFFSET_MINUS_4, // по доке нужно сделать при инициализации
// временно перевел XOUT в CMOS
IO_CFG_ADR,(IO_CFG_RST&~XOUT_OD),//(IO_CFG_RST|XOUT_OD), // настройка портов. Все как CMOS и IRQ активно в нуле, XOUT открфтый коллектор
// было убрано
XTAL_CFG_ADR,0x08, // по доке нужно сделать при инициализации
RX_CFG_ADR,((RX_CFG_RST)&~(RXOW_EN)), // автоподстройка включена и перезапись буфера выключена
TX_OFFSET_LSB_ADR,0x55, // множитель для синтезатора. Частота 732.6 Гц
TX_OFFSET_MSB_ADR,0x05, // Это частота между каналами. При переключении
XACT_CFG_ADR,(ACK_EN|END_STATE_SLEEP|ACK_TO_15X), // режим ответа. Авто ACK включен, после ACK в sleep и таймаут = 15x
TX_CFG_ADR,(PA_4_DBM|DATCODE_LEN_32|DATMODE_8DR), // 32 chip code и 250кБит 8DR
FRAMING_CFG_ADR,(SOP_EN|LEN_EN|4), // включаем поддержку SOP пакета для 32 chip code
PREAMBLE_ADR,0x01, // количество повторов преамбулы (0 - отключает преамбулу)
PREAMBLE_ADR,PREAMBLE_CODE_LSB_RST, // преамбула
PREAMBLE_ADR,PREAMBLE_CODE_MSB_RST, // преамбула
PWR_CTRL_ADR,((PWR_CTRL_RST|LV_IRQ_TH_1P8_V|PMU_OUTV_2P7)&~PMU_EN), // выключаем PMU (неиспользуется аппаратно)
// временно разрешил работу XOUT
XTAL_CTRL_ADR, XOUT_FNC_XOUT_FREQ,//XOUT_FNC_GPIO, // порт XOUT переводим в программный и незадействуем
DATA32_THOLD_ADR,0x03,//0x05, // устанавливаем значение в 05 для типовых приложений
RX_OVERRIDE_ADR,(ACK_RX),
TX_OVERRIDE_ADR,(ACK_TX_SEN),
#ifdef CRC_SEED
CRC_SEED_LSB_ADR,((byte)CRC_SEED), // загружаем CRC seed
CRC_SEED_MSB_ADR,(CRC_SEED>>8) // загружаем CRC seed
#else
CRC_SEED_LSB_ADR,0x00, // загружаем CRC seed
CRC_SEED_MSB_ADR,0x00 // загружаем CRC seed
#endif
};
В основном цикле произвожу установку канала (всегда константа) и записываю PN коды.
Далее произвожу попытку получить данные и в случае неудачи произвожу попытку передать синхропакет.
И так по циклу.
Вот этот цикл
CODE
// цикл проверки соединения
do{
// устанавливаем канал
Radio_set_channel(Protocol.channel);
if (Channels[Protocol.channel-1].present && Channels[Protocol.channel-1].connect)
set_pn_code(&PN_CODES[Channels[Protocol.channel-1].PN_code]);
else
reset_pn_code(0);
// слушаем канал
Protocol.packet_len=recive_radio(&Protocol.dat.mass);
// читаем уровень шумов
Channels[Protocol.channel-1].rssi=Radio_RSSI_read();
if (!Protocol.packet_len)
{// данных нет
if (Channels[Protocol.channel-1].present)
{
if (global_time_check(Channels[Protocol.channel-1].bind_time,PROTOCOL_BIND_TIME_OUT))
{// прошел таймаут, устройство не отвечает
// сбрасываем соединение
Channels[Protocol.channel-1].present=0;
Channels[Protocol.channel-1].connect=0;
}
}
else
{// Канал пуст. Проверим его на наличие обекта
// отправляем запрос на соединение
Bind_req_func();
if (Radio_count)
{// нашли канал
// читаем данные из канала
Protocol.packet_len=recive_radio(&Protocol.dat.mass);
}
}
}
if (Protocol.packet_len)
{// Уточнение. Данные есть
CommandParser(Protocol.dat.packet.hdr.type);
}
}while(1);
Вот процедуры передачи пакета
CODE
/*---------------------------------------------------------------------------
ПЕРЕДАЧА ПАКЕТА
Вход:
Длина передаваемых данных и указатель на буфер с данными
Выход:
1 = переданы, 0 = ошибка передачи.
---------------------------------------------------------------------------*/
bit transmit_radio(byte buffer_length, byte *tx_buffer)
{
data byte i;
if (Radio_status==RADIO_NOT_USE)
{
if (buffer_length>(MAX_RX_BUF-1)) return(0);
// очищаем буфер
do{
i=Get_Radio_byte(TX_IRQ_STATUS_ADR);
}while(!(i&TXB0_IRQ));
// настраиваем прерывания
Write_Radio(TX_CTRL_ADR,TX_CLR|TX_CTRL_RST);
// закачиваем данные
Write_Radio_data(TX_BUFFER_ADR,buffer_length,tx_buffer);
// устанавливаем длину
Write_Radio(TX_LENGTH_ADR,buffer_length);
// запускаем передачу
i=Get_Radio_byte(TX_CTRL_ADR);
Write_Radio(TX_CTRL_ADR,(TX_GO|i));
// сообщаем о статусе для того что бы позже контроллировать передачу на предмет реповтора данных
Radio_status=RADIO_TRANSMIT;
Radio_count=0;
return(1);
}else return(0);
}
Вот процедура контролирующая ход передачи данных
CODE
/*---------------------------------------------------------------------------
ОБРАБОТЧИК СОСТОЯНИЙ РАДИО
Вход:
статусная переменная radio
Выход:
изменение статуса radio
1 ошибка
---------------------------------------------------------------------------*/
bit radio_control(void)
{
register byte status;
if (Irq_radio)
{
Irq_radio=0;
if (Radio_status==RADIO_TRANSMIT)
{
status=Get_Radio_byte(TX_IRQ_STATUS_ADR);
if (status&(TXC_IRQ|TXE_IRQ))
{// есть прерывание
status&=(TXC_IRQ|TXE_IRQ);
if (status==TXC_IRQ)
{
if (!Radio_count) Radio_count=1;
Radio_status=RADIO_NOT_USE;
// Write_Radio(TX_CTRL_ADR,0x00);
}
else
{
Get_Radio_byte(RX_IRQ_STATUS_ADR);
Radio_count++;
if (Radio_count<TIME_OUT_TRANSMIT)
// повторяем передачу
Write_Radio(TX_CTRL_ADR,TX_GO|TX_CTRL_RST);
else
{// остановка реповтора
Radio_count=0;
Radio_status=RADIO_NOT_USE;
// Write_Radio(TX_CTRL_ADR,0x00);
return(1);
}
}
}
}
}
return(0);
}
Вот процедура приема данных
CODE
/*---------------------------------------------------------------------------
ПРИЕМ ПАКЕТА
Вход:
Указатель на буфер приема.
Выход:
Количество полученных байт. Если =0, значит ничего не полученно (или полученно с ошибками).
---------------------------------------------------------------------------*/
byte recive_radio(byte *rx_buffer)
{
data byte i,status=0;//-1;
data dword time;
if (Radio_status==RADIO_NOT_USE)
{
// инициируем прием.
Write_Radio(CLK_OVERRIDE_ADR,RXF);
Write_Radio(RX_CTRL_ADR,(RX_GO | RXC_IRQ | RXE_IRQ));
Get_Radio_byte(RSSI_ADR);
// входим в цикл ожидания данных
time=get_tic_count();
// цикл ожидания данных 20 ms
while (!global_time_check(time,20))
{
if (Irq_radio)
{// обработчик
Irq_radio=0;
status=Get_Radio_byte(RX_IRQ_STATUS_ADR);
if (status&(RXC_IRQ|RXE_IRQ|RXBERR_IRQ))
{// есть прерывание
if (status&(RXE_IRQ|RXBERR_IRQ))
{// ошибка
i=Get_Radio_byte(RX_COUNT_ADR);
if (i)
{
Read_Radio(RX_BUFFER_ADR,i);
while(Spi_busy);
i=0;
}
status=0;
break;
}
else
i=Get_Radio_byte(RX_COUNT_ADR);
status=0;
if (i)
{
Read_Radio(RX_BUFFER_ADR,i);
while(Spi_busy);
do{
*rx_buffer++=SPI_mas.dat[++status];
}while(status!=i);
}
break;
}
else
{
status=0;
i=Get_Radio_byte(RX_COUNT_ADR);
i=0;
}
}
status=0;
}
// при получении ошибки или завершения приема выводим приемник из режима приема
// читаем XACT_CFG_ADR
i=Get_Radio_byte(XACT_CFG_ADR);
// устанавливаем FRC_END_STATE
Write_Radio(XACT_CFG_ADR,i|FRC_END_STATE);
// и ждем пока не сбросит в XACT_CFG_ADR FRC_END_STATE
do{
i=Get_Radio_byte(XACT_CFG_ADR);
}while(i&FRC_END_STATE);
// отключаем приемник
Write_Radio(CLK_OVERRIDE_ADR,CLK_OVERRIDE_RST);
Write_Radio(RX_CTRL_ADR,0x00);
}
return(status);
}
Кто применял данную микросхему, какие трудности вообще возникали с ней?PS Под неустановившимся соединением я подразумеваю, что в буфере CYRF, в режиме приема, нет данных (буфер пуст и выход происходит по истечению таймаута 20mS). При этом в режиме приема, по датчику тока иногда наблюдаю синхронные провалы (синхронные с провалами на датчике тока второй микросхемы, находящейся в этот момент в режиме передачи) потребления тока (уменьшение потребеления). Т.е. ощущение что микросхема что-то получила, но в режим передачи подтверждения не перешла (возможно получила что-то битое), но при этом вывалилась из режима приема. Затем опять вошла в режим приема (потребление вернулось на начальный уровень). При этом прерывания об ошибке не возводится. Т.е. нет ошибки BAD CRC.
Сообщение отредактировал AndreyS - Jun 24 2009, 08:49
Удачи.