реклама на сайте
подробности

 
 
> CYRF*, Прошу помощи по освоению CYRF6936
AndreyS
сообщение Jun 24 2009, 08:33
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 235
Регистрация: 28-01-05
Из: Санкт-Петербург
Пользователь №: 2 276



Добрый день.

Начал работу с микросхемой 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


--------------------
Удачи.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AndreyS
сообщение Sep 14 2009, 11:05
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 235
Регистрация: 28-01-05
Из: Санкт-Петербург
Пользователь №: 2 276



Добрый день всем.

После пересматривания исходников от Cypress нашел ответ по проблеме зависания Radio при переходе из SLEEP режима. Программисты Cypress производят перевод Radio сначала в IDLE и только после этого начинают с ним работу. В документации о необходимости такой процедуры ничего не сказано. Указано лишь время просыпания Radio из SLEEP режима (5 ms).

Так и осталась тайной для меня почему через некоторый промежуток времени Radio на прием информации начинает браковать все входящие пакеты (сообщает о битом CRC). Наустанавливал в свой код столько костылей из Cypress'овских исходников, но однозначно сказать что они помогли я не могу (приемник так или иначе начинает браковать все входящие пакеты).

ЛЮДИ!! ПОМОГИТЕ. ЕСТЬ ТУТ КТО, КТО РАБОТАЛ С ДАННЫМ RADIO КОНТРОЛЛЕРОМ??

А то приходится ставить вопрос о применимости данного чипа в дальнейшем.

Параллельно производил измерение тока потребления системы от первичного источника питания (не претендую на точные цифры). Когда вся схема спит (CPU на пониженной и выключен генератор {потребление ядра десятки uA, периферия до 100uA}, с аналоговой части снято питание {потребление единицы uA}) получается что RADIO (если верить в то что проц действительно кушает uA) в разных энергосберегающих режимах кушает не совсем паспортные значения.

Источник напряжения 1.3 вольта, повышающий преобразователь и LDO формируют 3.3 вольта (повышающий формирует 3.7 вольта) оценочное КПД 70%
Теперь исходя из этих данных имеем следующее:
PMU не выключено, так как не использую.
Radio в SLEEP потребление на батареи 8 mA по расчета ток Radio = примерно (1.3*8mA*0.7)/3.3= 2 mA это много. По datasheet 10 uA (если PMU включено то 35 uA)
Radio в IDLE потребление на батареи 12 mA ток Radio = примерно 3.3 mA Тоже много, по доке около 1 mA.

Кончено я не точно смотрел КПД преобразователя питания, но у меня в системе есть светодиод на него даю 3 mA. По потреблению им тока от батареи я и вычислил КПД преобразователя.

ЛЮДИ!! ПОМОГИТЕ. ЕСТЬ ТУТ КТО, КТО РАБОТАЛ С ДАННЫМ RADIO КОНТРОЛЛЕРОМ?? Дайте плиз рабочий исходник процедуры включения этого чипа в режим приема


--------------------
Удачи.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 08:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01412 секунд с 7
ELECTRONIX ©2004-2016