Перейти к основному содержимому

Включение GigaSpaceWire

В этой статье описан пошаговый процесс включения канала GigaSpaceWire для процессора 1892ВМ206. Данный алгоритм реализован в примере.

Документация:

  • Руководство пользователя для микросхемы интегральной 1892ВМ206.

Алгоритм включения канала GigaSpaceWire для процессора 1892ВМ206

Установить значение регистра CR_PLL в зависимости от заданной частоты (смотрите таблицу 2.2). Разряды CLK_SEL_CORE[6:0] в значение 110100=52 или 110000=48. Разряд PLL_CORE_EN[7] (режим работы PLL_CORE) в значение "1" (включена).

#define FREQ 120
#define CR_PLL *((volatile unsigned int *)0xB82F4000)
CR_PLL = (FREQ == 120) ? 0x00000098 : 0x00000094;

Установить значение регистра CLK_EN в зависимости от заданной частоты (смотрите таблицу 2.3). Значение разряда CLKEN_CORE[0] = 1 (включить тактовую частоту, поступающую от PLL_CORE). Значение разряда CLKEN_SPFMIC[9:8] = 1 (включить тактовую частоту SPFMIC[1:0], поступающую от PLL_CORE).

Подождать 15 тактов частоты CPU.

#define CLK_EN *((volatile unsigned int *)0xB82F4004)
CLK_EN = 0x00000301;

Sleep( 15 );

Для открытия канала нужно выполнить следующий алгоритм:

Установка разряда PORT_REGIME (регистр MODE_R[0]), смотрите таблицу 16.2.

// Установка режима порта GSpW:
*mode_r |=0x1;

Сброс регистра PMA_MODE, смотрите таблицу 16.40. Разрядам EN_PMA_RX, EN_PMA_TX, PWDn_TX, PWDn_RX, PMA_RX_SPEED, PMA_TX_SPEED, LB_EN_RX, LB_EN_TX, COMMAEN, COMPARE_EN присваивается значение "0".

// Сброс PMA:
*pma_mode &= ~( (1<<13)|(1<<24)|(1<<0)|(1<<1)|(0x7F << 4) |
(0x7F << 17)|(1<<16)|(1<<25)|(1<<2)|(1<<3) );

Разряду BDS_RESET (регистр GIGA_SPW_MODE[3]) присваивается значение "1", смотрите таблицу 16.44. ::

// Cброс BDS:
*gspw_mode |= (1<<3);

Обнуляем разряды LINKDISABLED, AUTOSTART, LINKSTART, BDS_RESET, после чего присваиваем "1" разряду LINKDISABLED.

// Cброс параметров установки соединения (повторно):
*gspw_mode &= ~( (1<<0)|(1<<1)|(1<<2)|(1<<3) );
*gspw_mode |= 0x1;

Обнуляем разряды KOEFF_COMMA (регистр GIGA_SPW_TRANSMISSION_PARAMETERS[5:0]), смотрите таблицу 16.45. Записываем в регистр коэффициент comma, значение которого зависит от скорости соединения.

uint32_t GetCommaCoeff(uint32_t speed)
{
if (speed < 312)
return 1;
else
return 8;
}

uint32_t comma = GetCommaCoeff(speed);
// Установка значения comma:
*gspw_tp &= ~(0x3F<<0);
*gspw_tp |=(comma&0x3F)<<0;

Обнуляем DISCONNECT_COUNTER (регистр GIGA_SPW_TRANSMISSION_PARAMETERS[9:6]) и сразу задаём максимальное значение (0xF), смотрите таблицу 16.45.

// Установка значения disconnect_counter:
gspw_tp &= ~(0xF<<6);
gspw_tp |=(0xF&0xF)<<6;

Установка регистра PMA_MODE, смотрите таблицу 16.40. Ждём 155 тактов.

pma_mode = ((1&0x7f)<<4)|((3 & 0x3) << 11)|(1<<13)|((1 & 0x7F) << 17)|(1<<24)|(1<<0);
Sleep( 155 );

Установка регистра PMA_MODE, смотрите таблицу 16.40.

pma_mode = (1<<0)|(1<<13)|((rx_speed_k & 0x7F) << 4)|((3 & 0x3) << 11)|
((tx_speed_k & 0x7F) << 17)|(1<<24);

Установка регистра MODE_R, смотрите таблицу 16.2.

// Установка KOEFF_10_LOCAL и коэффициентов скоростей:
mode_r = (1<<0)|(k10<<1)|(4<<13)|(5<<16)|(1<<10);

Установка регистра GIGA_SPW_MODE, смотрите таблицу 16.44. Ждём 155 тактов.

gspw_mode = (1<<2)|((k10&0x1FF)<<9);
Sleep( 155 );

Установка регистра PMA_MODE, смотрите таблицу 16.40. Ждём 155 тактов.

pma_mode = (1<<0)|(1<<1)|(1<<2)|(1<<3)|((rx_speed_k & 0x7F) << 4)|((tx_speed_k & 0x7F) << 17)
|(1<<13)|(1<<24)|((1 & 0x3) << 11)|((3 & 0x3) << 14);
Sleep( 155 );

Установка регистра GIGA_SPW_MODE, смотрите таблицу 16.44.

gspw_mode = (1<<2)|((k10&0x1FF)<<9);

Установка регистра PMA_MODE, смотрите таблицу 16.40.

pma_mode = (1<<0)|(1<<1)|(1<<2)|(1<<3)|((rx_speed_k & 0x7F) << 4)|((tx_speed_k & 0x7F) << 17)|
(1<<13)|(1<<24)|((1 & 0x3) << 11)|((3 & 0x3) << 14);

После настроек всех регистров установите задержку (длительность ожидания настраивается экспериментально).

SleepMs(1);

Установление связи в канале GigaSpaceWire

Установка регистра GIGA_SPW_MODE, смотрите таблицу 16.44. Проверка наличия переменных и, если определено, то присваивает "1" разрядам AUTOSTART и LINKSTART

#ifdef AUTOSTART
*gspw_mode |= (1<<1);
#endif
#ifdef LINKSTART
*gspw_mode |= (1<<2);
#endif

Сбрасываем регистр GIGA_SPW_MODE (присваиваем максимальное значение), смотрите таблицу 16.43.

*gspw_status = 0xffffffff;

Проверка канала

Функция, которая проверяет статус канала.

uint32_t IsConnected( uint32_t chNum )
{
int tOut = 10000;
int off;
switch(chNum) {
case 0: off=CH0; break;
case 1: off=CH1; break;
}
volatile uint32_t *state_r = ( volatile uint32_t* ) ( off + STATE_R );

while(tOut)
{
if((*state_r)&0x20)
*state_r |= 0x20;
if((*state_r)&0x40)
*state_r |= 0x40;
if((*state_r)&0x100)
return 0;
if((*state_r)&0x80)
return 1;

tOut--;
}

return 0;
}

Проверка работоспособности канала осуществляется передачей данных между контроллерами. Отправляется пакет из 16 32-битных слов, принимается вторым портом и проверяется достоверность принятых данных. Если ошибок не обнаружено цикл завершается.

  while(IsConnected(0)&&IsConnected(1))
{
memset(rv_data,0,packet_len*sizeof(int));
gswic_receiver_packet_run(rv_data,Desc,packet_len*sizeof(int));
gswic_send_packet(tr_data,txDesc,packet_len*sizeof(int),1);
gswic_receiver_packet_wait();
for(i=0;i<packet_len;i++)
{
err_counter += (tr_data[i]!=rv_data[i]) ? 1 : 0 ;
}
if(!err_counter)
{
/* Place breakpoint here */
asm("nop");
break;
}
}

Алгоритм отключения канала GigaSpaceWire

Закрытие канала проходит по алгоритму, описанному ниже.

Сброс регистра GIGA_SPW_MODE, смотрите таблицу 16.44. Разрядам LINKDISABLED, AUTOSTART, LINKSTART, BDS_RESET присваивается значение "0". Сразу после этого разряду LINKDISABLED присваивается значение "1".

*gspw_mode &= ~( (1<<0)|(1<<1)|(1<<2)|(1<<3) );
*gspw_mode |= (1<<0);

Установка регистра STATE_R, смотрите таблицу 16.3. В разряды PORT_CONNECTED и PORT_ERRORED записывается "1", что приводит к сбросу.

*state_r |= (1<<5)|(1<<6);

Сброс регистра PMA_MODE, смотрите таблицу 16.40. Разрядам EN_PMA_RX, EN_PMA_TX, PWDn_TX, PWDn_RX, PMA_RX_SPEED, PMA_TX_SPEED, LB_EN_RX, LB_EN_TX, COMMAEN, COMPARE_EN присваивается значение "0". ::

*pma_mode &= ~( (1<<13)|(1<<24)|(1<<0)|(1<<1) |
((0x7F & 0x7F) << 4)|((0x7F & 0x7F) << 17)|(1<<16)|(1<<25)|(1<<2)|(1<<3) );

Ждём 155 тактов + 1 мс.

Sleep( 155 );
SleepMs(1);

Установка регистра GIGA_SPW_MODE, смотрите таблицу 16.44.

Разряду BDS_RESET присваивается "1", проходит синхронный сброс порта gigaSpW. После этого обнуляем разряды LINKDISABLED, AUTOSTART, LINKSTART, BDS_RESET, после чего присваиваем "1" разряду LINKDISABLED.

*gspw_mode |= (1<<3);
*gspw_mode &= ~( (1<<0)|(1<<1)|(1<<2)|(1<<3) );
*gspw_mode |= (1<<0);