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

Включение GigaSpaceWire

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

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

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

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

Установить значение регистра CR_PLL в зависимости от заданной частоты (см. таблицу 2.2 руководства пользователя):

  • Разряды CLK_SEL_CORE[6:0] в значение 0x18 (24×5=120 МГц) или 0x14 (20×5=100 МГц).
  • Разряд PLL_CORE_EN[7] (режим работы PLL_CORE) в значение "1" (включена).
#define FREQ 120
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.

CLK_EN = 0x00000301;

Sleep(15);

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

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

// Установка режима порта GSpW:
SPFMIC_MODE_R(ch) |= (1 << PORT_REGIME_OFFSET) | (1 << DMA_ENABLED_OFFSET);

Сброс регистра PMA_MODE, см. таблицу 16.40.

// Сброс PMA:
SPFMIC_PMA_MODE(ch) = 0;

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

// Cброс BDS:
SPFMIC_GIGA_SPW_MODE(ch) |= (1 << BDS_RESET_OFFSET);

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

// Cброс параметров установки соединения (повторно):
SPFMIC_GIGA_SPW_MODE(ch) &=~((1 << LINKDISABLED_OFFSET)|(1 << AUTOSTART_OFFSET)|
(1 << LINKSTART_OFFSET) | (1 << BDS_RESET_OFFSET));
SPFMIC_GIGA_SPW_MODE(ch) |= (1 << LINKDISABLED_OFFSET);

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

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

// Установка значения comma и disconnect_counter:
SPFMIC_GIGA_SPW_TRANSMISSION_PARAMETERS(ch) &=~(KOEFF_COMMA_MASK << KOEFF_COMMA_OFFSET)|
(DISCONNECT_COUNTER_MASK << DISCONNECT_COUNTER_OFFSET);

SPFMIC_GIGA_SPW_TRANSMISSION_PARAMETERS(ch) |=(comma & KOEFF_COMMA_MASK) << KOEFF_COMMA_OFFSET |
(0xF & DISCONNECT_COUNTER_MASK) << DISCONNECT_COUNTER_OFFSET;

Установить регистра PMA_MODE на низкой скорости, см. таблицу 16.40. Подождать ~155 тактов.

SPFMIC_PMA_MODE(ch) = ((1 & PMA_RX_SPEED_MASK) << PMA_RX_SPEED_OFFSET) |
((3 & ALIGN_MODE_MASK) << ALIGN_MODE_OFFSET) |
(1 << EN_PMA_RX_OFFSET) |
((1 & PMA_TX_SPEED_MASK) << PMA_TX_SPEED_OFFSET) |
(1 << EN_PMA_TX_OFFSET) | (1 << PWDn_TX_OFFSET);

Sleep(155);

Повысить скорость PMA_MODE, см. таблицу 16.40.

SPFMIC_PMA_MODE(ch) |=((rx_speed_k & PMA_RX_SPEED_MASK) << PMA_RX_SPEED_OFFSET) |
((tx_speed_k & PMA_TX_SPEED_MASK) << PMA_TX_SPEED_OFFSET);

Установить режим LinkStart (или AutoStart) и koeff_10_local. Подождать ~155 тактов.

if (mode == AUTOSTART)
SPFMIC_GIGA_SPW_MODE(ch) = (1 << AUTOSTART_OFFSET) |
((k10 & KOEFF_10_LOCAL_MASK) << KOEFF_10_LOCAL_OFFSET);
else if (mode == LINKSTART)
SPFMIC_GIGA_SPW_MODE(ch) = (1 << LINKSTART_OFFSET) |
((k10 & KOEFF_10_LOCAL_MASK) << KOEFF_10_LOCAL_OFFSET);

Sleep(155);

Включить приемник PMA, см. таблицу 16.40. Подождать ~155 тактов + 1мс.

SPFMIC_PMA_MODE(ch) |= (1 << PWDn_RX_OFFSET) | (1 << COMMA_EN_OFFSET) |
(1 << COMPARE_EN_OFFSET) |
((1 & ALIGN_MODE_MASK) << ALIGN_MODE_OFFSET) |
((3 & CDR_MODE_MASK) << CDR_MODE_OFFSET);

Сбрасываем регистр GIGA_SPW_MODE, см. таблицу 16.43.

SPFMIC_GIGA_SPW_STATUS(ch) = 0xffffffff;

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

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

uint32_t IsConnected(uint32_t ch) {
int tOut = 10000;

while (tOut) {
if ((SPFMIC_STATE_R(ch)) & (1 << PORT_CONNECTED_OFFSET))
SPFMIC_STATE_R(ch) |= (1 << PORT_CONNECTED_OFFSET);
if ((SPFMIC_STATE_R(ch)) & (1 << PORT_ERRORED_OFFSET))
SPFMIC_STATE_R(ch) |= (1 << PORT_ERRORED_OFFSET);
if ((SPFMIC_STATE_R(ch)) & (1 << PORT_CONNECT_OFFSET)) return 1;
if ((SPFMIC_STATE_R(ch)) & (1 << PORT_ERROR_OFFSET)) return 0;

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".

SPFMIC_GIGA_SPW_MODE(ch) &= ~((1 << LINKDISABLED_OFFSET) | (1 << AUTOSTART_OFFSET) |
(1 << LINKSTART_OFFSET) | (1 << BDS_RESET_OFFSET));
SPFMIC_GIGA_SPW_MODE(ch) |= (1 << LINKDISABLED_OFFSET);

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

SPFMIC_STATE_R(ch) |= (1 << PORT_CONNECTED_OFFSET) | (1 << PORT_ERRORED_OFFSET);

Сброс регистра 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". Ждём 155 тактов + 1 мс.

SPFMIC_PMA_MODE(ch) &= ~((1 << EN_PMA_RX_OFFSET) | (1 << EN_PMA_TX_OFFSET) |
(1 << PWDn_TX_OFFSET) | (1 << PWDn_RX_OFFSET) |
((0x7F & PMA_RX_SPEED_MASK) << PMA_RX_SPEED_OFFSET) |
((0x7F & PMA_TX_SPEED_MASK) << PMA_TX_SPEED_OFFSET) |
(1 << LB_EN_RX_OFFSET) | (1 << LB_EN_TX_OFFSET) |
(1 << COMMA_EN_OFFSET) | (1 << COMPARE_EN_OFFSET));

Sleep(155);
SleepMs(1);

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

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

SPFMIC_GIGA_SPW_MODE(ch) &= ~((1 << LINKDISABLED_OFFSET) | (1 << AUTOSTART_OFFSET) |
(1 << LINKSTART_OFFSET) | (1 << BDS_RESET_OFFSET));
SPFMIC_GIGA_SPW_MODE(ch) |= (1 << LINKDISABLED_OFFSET);