Описание библиотеки микросхемы 5023ВС016 процессора "Спутник"
spacewire_test.c
См. документацию.
1 
30 #include "spacewire_test.h"
31 
32 
33 const uint32_t sys_freq = 80000000; // Системная частота
34 const uint32_t spw_freq = 100000000; // Системная частота для Spacewire
35 
36 char dbg_buffer[256]; // Отладочный буфер
37 
38 #define FAST_SPW_TEST // Включаем тест
39 #define FULL_LOG // Включаем лог
40 
41 #ifdef FAST_SPW_TEST
42 
43 #define SPW_TIMEOUT_INIT 8000000 // Таймаут
44 #define SPW_TIMEOUT_TX 5000000 // Таймаут TX
45 #define SPW_TIMEOUT_RX 5000000 // Таймаут RX
46 
47 unsigned int spw1_intr_flag; // Флаг SPW1
48 unsigned int spw2_intr_flag; // Флаг SPW2
49 
53 void Spacewire1_IRQ (void)
54 {
55  spw1_intr_flag = 1; // Флаг SPW1 = 1
56 }
57 
61 void Spacewire2_IRQ (void)
62 {
63  spw2_intr_flag = 1; // Флаг SPW2 = 1
64 }
65 
69 void SetDefaults(SPW_T* pSPW, unsigned char spw_number)
70 {
71  if (pSPW->STATUS & SW_STATUS_DISCONNECT_ERR)
72  {
73  PRINT("Spacewire %i: Got disconnect error", spw_number); // ошибка соединения
74  }
75 
76  if (pSPW->STATUS & SW_STATUS_PARITY_ERR)
77  {
78  PRINT("Spacewire %i: Got parity error", spw_number); // ошибка четности
79  }
80 
81  if (pSPW->STATUS & SW_STATUS_ESCAPE_ERR)
82  {
83  PRINT("Spacewire %i: Got escape error", spw_number); // ошибка escape
84  }
85 
86  if (pSPW->STATUS & SW_STATUS_CREDIT_ERR)
87  {
88  PRINT("Spacewire %i: Got credit error", spw_number); // ошибка credit
89  }
90 
91  if (pSPW->STATUS & SW_STATUS_AHB_ERR)
92  {
93  PRINT("Spacewire %i: AHB error occured", spw_number); // ошибка шины AHB
94  }
95 
96  pSPW->CONTROL = SW_CONTROL_RESET_AMBA | //сбрасывает контроллер
97  SW_CONTROL_RESET_DMA | //сброс DMA
98  SW_CONTROL_CANCEL_TX_DMA ; //Запись «1» прерывает работу TXDMA и RXDMA
99 
100  pSPW->TXSCALER = 9; // Регистр делителя тактовых сигналов
101  pSPW->RXDESCPTR = 0; // Регистр указателя на таблицу дескрипторов приема
102  pSPW->TXDESCPTR = 0; // Регистр указателя на таблицу дескрипторов передачи
103 }
104 
108 void ResetSPW()
109 {
110  SetDefaults(SPW1, 1); // Установка регистров
111  SetDefaults(SPW2, 2); // Установка регистров
112 }
113 
114 #define PACKET_SIZE_WORDS 256 // Размер слова
115 #pragma data_alignment = 0x200
116 #pragma location=".noinit"
118 #pragma data_alignment = 0x200
119 #pragma location=".noinit"
121 #pragma location=".noinit"
122 unsigned int txdataA [PACKET_SIZE_WORDS]; // буфер данных tx
123 #pragma location=".noinit"
124 unsigned int rxdataB [PACKET_SIZE_WORDS]; // буфер данных rx
125 
126 unsigned char cur_dscr = 0;
127 
131 void InitSPWDscr(SPW_T* pSPW, SPW_DMA_DSC_TBL_T* pDSC_TBL, uint32_t* dscr_buf_tx, uint32_t* dscr_buf_rx)
132 {
133  pDSC_TBL->TXDsc[cur_dscr].HEADER = (1<<16) | //EN
134  (PACKET_SIZE_WORDS*4); //число байт для передачи
135  pDSC_TBL->TXDsc[cur_dscr].DATA_PTR = dscr_buf_tx;
136  pDSC_TBL->TXDsc[(cur_dscr+1)%SPW_DSC_COUNT].HEADER = 0;
137  pDSC_TBL->TXDsc[(cur_dscr+1)%SPW_DSC_COUNT].DATA_PTR = 0;
138  pSPW->TXDESCPTR = (uint32_t)pDSC_TBL->TXDsc + (cur_dscr << 3);
139 
140  pDSC_TBL->RXDsc[cur_dscr].HEADER = (1<<16) | //EN
141  (1<<18) |
142  (PACKET_SIZE_WORDS*4); //число байт для передачи
143  pDSC_TBL->RXDsc[cur_dscr].DATA_PTR = dscr_buf_rx;
144  pDSC_TBL->RXDsc[(cur_dscr+1)%SPW_DSC_COUNT].HEADER = 0;
145  pDSC_TBL->RXDsc[(cur_dscr+1)%SPW_DSC_COUNT].DATA_PTR = 0;
146  pSPW->RXDESCPTR = (uint32_t)pDSC_TBL->RXDsc + (cur_dscr << 3);
147 
148  cur_dscr++;
150 }
151 
152 unsigned int* spwA_intr_flag; // Указатель Флага SPWA
153 unsigned int* spwB_intr_flag; // Указатель Флага SPWB
154 unsigned char odd_even = 0;
155 
159 unsigned int SpacewireTransmit(SPW_T* pSPWA, SPW_T* pSPWB, int clk_divisor)
160 {
161  if (pSPWA == (SPW_T*)SPW1)
162  {
165 #ifdef FULL_LOG
166  PRINTSTREAM("Transmit from spw1 to spw2");
167 #endif
168  }
169  else
170  {
173 #ifdef FULL_LOG
174  PRINTSTREAM("Transmit from spw2 to spw1");
175 #endif
176  }
177 #ifdef FULL_LOG
178  PRINT(", speed = %i Mbit/s\n", spw_freq/1000000/(clk_divisor+1));
179 #endif
180  pSPWA->TXSCALER = SW_TXSCALER_DIVISOR(clk_divisor); // делитель частоты тактового сигнала передатчика A
181  pSPWB->TXSCALER = SW_TXSCALER_DIVISOR(clk_divisor); // делитель частоты тактового сигнала передатчика B
182 
183  //Инициализация
184  pSPWA->CONTROL &= ~SW_CONTROL_LINK_START;
185  pSPWA->CONTROL |= SW_CONTROL_LINK_START; // Linkstart; запись «1» разрешает установку соединения.
186 
187  pSPWB->CONTROL &= ~SW_CONTROL_LINK_START;
188  pSPWB->CONTROL &= ~SW_CONTROL_AUTOSTART;
189  pSPWB->CONTROL |= SW_CONTROL_AUTOSTART; // Autostart; Запись «1» разрешает автоматическую установку соединения в случае потери.
190 
192  pSPWA->CONTROL |= SW_CONTROL_INT_EN_RX_DSCR_COMPLETE; // Разрешает прерывания по завершению RX , если дескриптор IE=1
193 
195  pSPWB->CONTROL |= SW_CONTROL_INT_EN_RX_DSCR_COMPLETE; // Разрешение прерывания по завершению RX дескриптора при IE = «1»
196 
197 
198  unsigned int timeout;
199  //Ожидает соединения
200  timeout = 0;
201  while(!((((pSPWA->STATUS)&SW_STATUS_LINK_STATUS_ENABLED)==0x03)&&
202  (((pSPWB->STATUS)&SW_STATUS_LINK_STATUS_ENABLED)==0x03))) // Cтатус Link контроллера: запущен
203  if (timeout++>SPW_TIMEOUT_INIT)
204  {
205  PRINT("ERROR: spacewire connection timeout\n");
206  ResetSPW();
207  return 1;
208  }
209 
210  unsigned int value = 0;
211  for (unsigned int i=0; i<PACKET_SIZE_WORDS; i++)
212  {
213  txdataA[i] = (odd_even)?value:~value;
214  if (i < 32)
215  value = (value << 1) + 1;
216  else if (i < 64)
217  value = (value << 1);
218  else
219  value += 0x01010101;
220  }
221  InitSPWDscr(pSPWA, &SPWA_DSC_TBL, &txdataA[0], 0);
222  InitSPWDscr(pSPWB, &SPWB_DSC_TBL, 0, &rxdataB[0]);
223 
224  spw1_intr_flag = 0;
225  spw2_intr_flag = 0;
226 
227  //Старт TX_A RX_B DMA
228  pSPWA->CONTROL |= SW_CONTROL_RESTART_TX_DMA; // запуск TXDMA A
229  pSPWB->CONTROL |= SW_CONTROL_RESTART_RX_DMA; // запуск RXDMA B
230 
231  //Ожидание TX_A
232  timeout = 0;
233  while(!(SPWA_DSC_TBL.TXDsc[0].HEADER&(1<<19)))
234  if (timeout++>SPW_TIMEOUT_TX)
235  {
236  PRINT("ERROR: spacewire TX_A timeout\n");
237  ResetSPW();
238  return 2;
239  }
240 
241  //Ожидание RX_B
242  timeout = 0;
243  while(*spwB_intr_flag==0)
244  {
245  if (timeout++>SPW_TIMEOUT_RX)
246  {
247  PRINT("ERROR: spacewire RX_B timeout\n");
248  ResetSPW();
249  return 3;
250  }
251  }
252 
253  //Сравнение
254  unsigned char data_error = 0;
255  for (unsigned int i=0; i<PACKET_SIZE_WORDS; i++)
256  if (rxdataB[i] != txdataA[i])
257  {
258  PRINT("ERROR: spacewire data not correct\n");
259  PRINT("Word #%i Expected: %x Received: %x", i, txdataA[i], rxdataB[i]);
260  if (data_error++ > 10)
261  break;
262  }
263  if (data_error)
264  {
265  ResetSPW();
266  return 4;
267  }
268 
269  return 0; //OK
270 }
271 
276 {
277 
278  GPIO_G->ALTFUNCSET |= (uint32_t)(1<<4); // SW1_SIN
279  GPIO_G->ALTFUNCSET |= (uint32_t)(1<<6); // SW1_SOUT
280 
281  GPIO_G->ALTFUNCSET |= (uint32_t)(1<<5); // SW1_DIN
282  GPIO_G->ALTFUNCSET |= (uint32_t)(1<<7); // SW1_DOUT
283 
284  GPIO_G->ALTFUNCSET |= (uint32_t)(1<<8); // SW2_SIN
285  GPIO_G->ALTFUNCSET |= (uint32_t)(1<<10); // SW2_SOUT
286 
287  GPIO_G->ALTFUNCSET |= (uint32_t)(1<<9); // SW2_DIN
288  GPIO_G->ALTFUNCSET |= (uint32_t)(1<<11); // SW2_DOUT
289 
290 }
291 
296 {
297  PRINT("Spacewire test - start\n");
298  SPW_Init(SPW1); // Инициализация модуля SPW1
299  SPW_Init(SPW2); // Инициализация модуля SPW2
300  SPW_freq(1); // Тактирование внутрисистемной частотой
301  NVIC_EnableIRQ(Spacewire1,16); // Разрешение прерывания SPW1
302  NVIC_EnableIRQ(Spacewire2,17); // Разрешение прерывания SPW2
303  Gpio_Spacewire_Init(); // Инициализация портов gpio для работы с модулем SpaceWire
304  unsigned int result = 0; // Результат
305  for(int clk = 0; clk<16; clk+=2)
306  {
307  result += SpacewireTransmit(SPW1, SPW2, clk); // Передача данных из SPW1 в SPW2
308  result += SpacewireTransmit(SPW2, SPW1, clk); // Передача данных из SPW2 в SPW1
309  }
310  odd_even = (1-odd_even);
311  if (!result)
312  {
313  PRINT("Test result - OK\n");
314  }
315  else
316  {
317  PRINT("Test result - FAILED\n");
318  }
319 }
320 
321 #endif
322 
#define SW_STATUS_AHB_ERR
Definition: spacewire.h:86
volatile uint32_t HEADER
Definition: spacewire.h:138
#define PRINT(...)
Макросы для использования отладочного выхода
Definition: debug_uart.h:48
__RW uint32_t TXSCALER
Definition: spacewire.h:44
#define SW_CONTROL_INT_EN_RX_DSCR_COMPLETE
Definition: spacewire.h:68
Структура для таблицы DMA дескрипторов Spacewire.
Definition: spacewire.h:145
__RO uint32_t STATUS
Definition: spacewire.h:43
int data_error
#define PRINTSTREAM(...)
Печать в СОМ порт
Definition: debug_uart.h:49
#define SW_STATUS_ESCAPE_ERR
Definition: spacewire.h:82
#define SPW_TIMEOUT_RX
__RW uint32_t RXDESCPTR
Definition: spacewire.h:46
#define SPW1
Указатель на структуру SPW1.
void NVIC_EnableIRQ(IRQn_T IRQn, uint32_t vec)
Разрешение прерывания
Definition: system.c:74
char dbg_buffer[256]
Отладочный буфер
#define SW_STATUS_LINK_STATUS_ENABLED
Definition: spacewire.h:79
#define SPW2
Указатель на структуру SPW2.
void Spacewire2_IRQ(void)
Обработчик прерывания для Spacewire 2.
#define SW_CONTROL_RESTART_RX_DMA
Definition: spacewire.h:63
void SPW_Init(SPW_T *pSPW)
Инициализация SpaceWire.
Definition: spacewire.c:59
void Spacewire1_IRQ(void)
Обработчик прерывания для Spacewire 1.
#define PACKET_SIZE_WORDS
#define GPIO_G
Указатель на структуру GPIO_G.
#define SPW_DSC_COUNT
Definition: spacewire.h:36
unsigned char cur_dscr
unsigned int * spwB_intr_flag
#define SW_TXSCALER_DIVISOR(x)
Макросы для TXSCALER.
Definition: spacewire.h:97
unsigned int SpacewireTransmit(SPW_T *pSPWA, SPW_T *pSPWB, int clk_divisor)
Передача данных
void SpacewireInternal_Test()
Тест Spacewire.
#define SW_CONTROL_LINK_START
Definition: spacewire.h:59
#define SW_CONTROL_RESET_DMA
Definition: spacewire.h:58
#define SW_CONTROL_AUTOSTART
Definition: spacewire.h:60
unsigned int spw2_intr_flag
unsigned int * spwA_intr_flag
#define SW_CONTROL_CANCEL_TX_DMA
Definition: spacewire.h:65
SPW_DMA_DSC_T RXDsc[SPW_DSC_COUNT]
Definition: spacewire.h:148
void SPW_freq(uint8_t freq_num)
Выбор тактовой частоты блоков Spacewire.
Definition: spacewire.c:72
#define SW_STATUS_DISCONNECT_ERR
Definition: spacewire.h:80
void ResetSPW()
Сброс регистров
__RW uint32_t TXDESCPTR
Definition: spacewire.h:47
#define SPW_TIMEOUT_INIT
void SetDefaults(SPW_T *pSPW, unsigned char spw_number)
Установка регистров
Этот файл содержит структуры, макросы и функции необходимые необходимые для тестовой программы для ап...
unsigned int spw1_intr_flag
#define SW_CONTROL_RESTART_TX_DMA
Definition: spacewire.h:64
SPW_DMA_DSC_T TXDsc[SPW_DSC_COUNT]
Definition: spacewire.h:147
#define SW_STATUS_PARITY_ERR
Definition: spacewire.h:81
unsigned int rxdataB[PACKET_SIZE_WORDS]
#define SW_STATUS_CREDIT_ERR
Definition: spacewire.h:83
const uint32_t sys_freq
Системная частота
#define SPW_TIMEOUT_TX
SPW_DMA_DSC_TBL_T SPWA_DSC_TBL
uint32_t * DATA_PTR
Definition: spacewire.h:139
SPW_DMA_DSC_TBL_T SPWB_DSC_TBL
void Gpio_Spacewire_Init()
Инициализация GPIO для модуля Spacewire.
unsigned char odd_even
void InitSPWDscr(SPW_T *pSPW, SPW_DMA_DSC_TBL_T *pDSC_TBL, uint32_t *dscr_buf_tx, uint32_t *dscr_buf_rx)
Инициализация Spacewire.
unsigned int txdataA[PACKET_SIZE_WORDS]
const uint32_t spw_freq
Структура для доступа к регистрам Spacewire.
Definition: spacewire.h:40
__RW uint32_t CONTROL
Definition: spacewire.h:42
#define SW_CONTROL_RESET_AMBA
Макросы для CONTROL.
Definition: spacewire.h:57