Exemple #1
0
HRESULT UmxSender::Transmit(bool log)
{
	if (!transferAllocated)
		return -1;

	HRESULT hr = -1;

	hr = SoraURadioTx(Radio::Current()->GetRadioNum(), txID);

	if (log)
	{
		logger->Log(LOG_FUNC_CALL, L"SoraURadioTx called for radio %d\n", Radio::Current()->GetRadioNum());
	}

	if (FAILED(hr))
	{
		logger->Log(LOG_ERROR, L"SoraURadioTx failed. ret = %x\r\n", hr);
		return -1;
	}
	else
	{
		if (log)
		{
			logger->Log(LOG_SUCCESS, L"success\n");		
		}
		return S_OK;
	}
}
BOOLEAN DoDot11BTx(void* ctx)
{
    // Alias
    Monitor& monitor = ((TxContext *)ctx)->monitor;
    const Config& config = ((TxContext *)ctx)->config;

    monitor.Query(true);

	HRESULT hr = SoraURadioTx(TARGET_RADIO, TxID);
	if (FAILED(hr))
	{
		printf("[dot11b:tx] tx failed\n");
		//break;
	}
    else
    {
        monitor.IncGoodCounter();
        monitor.IncThroughput(config.GetPayloadLength());
    }

    // Note: if we send too fast, the RX part cannot demodulate all the frames,
    // and the performance depends on the entry time, ie. not same in every experiment. 
    SoraStallWait(&tsinfo, 10000); // not to send too fast
    return TRUE;
}
Exemple #3
0
// Transit a buffer of <size> complex16 numbers
// ptr has to be 16 aligned and has to have space for x8 complex16 numbers, due to efficien packing to complex8
void writeSora(BlinkParams *params, complex16 *ptr, ULONG size)
{
    HRESULT hr;
	ULONG TxID;

	ULONG dbg=0;

	if (size*2 > params->radioParams.TXBufferSize)
	{
		fprintf (stderr, "Error: Sora Tx buffer too small (%ld needed)!\n", 2*size );
		exit(1);
	}

	// Saturated packing need 16-bit aligned pointers since it uses SSE
	if ((ULONG)ptr & 0xF > 0)
	{
		fprintf (stderr, "Error: Tx ptr has to be 16 aligned!\n");
		exit(1);
	}

	// Saturated pack from complex16 (default Blink TX type) to complex8
	vcs *vPtr = (vcs*)ptr;
	unsigned int index = 0;
	for(int i=0; i<size/4; i+=2)
	{
        vcs s1, s2;
        s1 = vPtr[i];
        s2 = vPtr[i+1];
        vcb b = (vcb)saturated_pack((vs&)s1, (vs&)s2);

		char *dst = (char *) params->TXBuffer;
		memcpy((void*)(dst+index), (void*) (&b), sizeof(vcb));
		index += sizeof(vcb);

	}


	// DEBUG: 
	//hr = SoraURadioTransferEx(params->radioParams.radioId, params->TXBuffer, 2*size, &TxID);	
	hr = SoraURadioTransferEx(params->radioParams.radioId, params->TXBuffer, 4*size, &TxID);	

    if (!SUCCEEDED(hr))
    {
		fprintf (stderr, "Error: Fail to transfer Sora Tx buffer!\n" );
		exit(1);
	}

	hr = SoraURadioTx(params->radioParams.radioId, TxID);
    if (!SUCCEEDED(hr))
    {
		fprintf (stderr, "Error: Fail to transmit Sora Tx buffer!\n" );
		exit(1);
	}

    hr = SoraURadioTxFree(params->radioParams.radioId, TxID);
}
Exemple #4
0
BOOLEAN DoDot11ATx(void* ctx)
{
    // Alias
    Monitor& monitor = ((TxContext *)ctx)->monitor;
    const Config& config = ((TxContext *)ctx)->config;

    monitor.Query(true);

	HRESULT hr = SoraURadioTx(TARGET_RADIO, TxID);
	if (FAILED(hr))
	{
		printf("[dot11b:tx] tx failed\n");
		//break;
	}
    else
    {
        monitor.IncGoodCounter();
        monitor.IncThroughput(config.GetPayloadLength());
    }
    SoraStallWait(&tsinfo, 10000); // not to send too fast
    return TRUE;
}
Exemple #5
0
// Buffers are ready, transfer them
DWORD WINAPI SoraTXWorker(void * pParam)
{
	HRESULT hr = S_OK;
	bool transferred = false;
	bool idle_detected = FALSE;
	writeSoraCtx *ctx = (writeSoraCtx *)pParam;

	ULONG firstTx32, lastTx32;
	ULONG cnt_tx = 0, cnt_rx = 0;

	ULONG samp_PC_queue_ptr = 0;
	ULONG samp_FPGA_queue_ptr = 0;
	ULONG samp_queue_subsample = 0;

	memset(samp_PC_queue, 0, sizeof(ULONGLONG)*MAX_NO_TX_BUFS);
	memset(samp_FPGA_queue, 0, sizeof(ULONGLONG)*MAX_CMD_FIFO_QUEUE_SIZE);
	samp_RX_queue_full = 0;
	samp_RX_queue_free = 0;

	bool blockPC = false;
	bool blockFPGA = false;

	ctx->idleTXDetected = 0;

	ULONGLONG cnt_rnd = 0;
	cnt_samp_FPGA_underflow = 0;
	memset(samp_FPGA_underflow, 0, sizeof(ULONGLONG)* DEB_MAX_UNDERFLOW_QUEUE);


	while (!rx_init_done || !tx_init_done);

	// Synchronize initial queue positions
	hr = ReadRegister(0x0550, &lastTx32);
	hr = ReadRegister(0x0554, &firstTx32);
	ctx->lastTx = lastTx32;
	ctx->firstTx = firstTx32;

	// TODO: here we might want to cache-align all the data to avoid cache misses
	while (true)
	{
		bool bPC = ctx->transferBuf != ctx->prepareBuf;
		bool bFPGA = diff_wrap(ctx->lastTx, ctx->firstTx) < cmd_fifo_queue_size;
		blockPC = blockPC || (!bPC);
		blockFPGA = blockFPGA || (!bFPGA);
		if (bPC && bFPGA)
		{
			int queuePos = ctx->lastTx % cmd_fifo_queue_size;
			hr = SoraURadioTransferEx(TARGET_RADIO_TX, ctx->TXBuffers[ctx->transferBuf],
				ctx->TXBufferSize * sizeof(complex16), &(ctx->BufID[queuePos]));
			hr = SoraURadioTx(TARGET_RADIO_TX, ctx->BufID[queuePos]);
			ctx->lastTx++;

			if (!SUCCEEDED(hr))
			{
				printf("SoraURadioTransferEx %d failed!\n", ctx->transferBuf);
				return FALSE;
			}
			ctx->transferBuf = (ctx->transferBuf + 1) % no_tx_bufs;

			// Store queue size samples for debugging
			ULONG d1 = diff_wrap_max((ULONG)ctx->prepareBuf, (ULONG)ctx->transferBuf, no_tx_bufs);
			d1 = min(d1, MAX_NO_TX_BUFS);
			ULONG d2 = diff_wrap_max(ctx->lastTx, ctx->firstTx, cmd_fifo_queue_size);
			d2 = min(d2, MAX_CMD_FIFO_QUEUE_SIZE);
			samp_PC_queue[d1] ++;
			samp_FPGA_queue[d2] ++;

			if (d2 < 6) {
				samp_FPGA_underflow[cnt_samp_FPGA_underflow] = cnt_rnd + 1;
				cnt_samp_FPGA_underflow = min(cnt_samp_FPGA_underflow + 1, DEB_MAX_UNDERFLOW_QUEUE);
			}

			if (blockPC) ctx->transferBlocked++;
			if (blockFPGA) ctx->transferBlockedFPGA++;
			blockPC = false;
			blockFPGA = false;
		}


		hr = ReadRegister(0x0550, &lastTx32);
		hr = ReadRegister(0x0554, &firstTx32);

		// Don't free the one just dequeued as the transmission could still be ongoing
		// Only free once the subsequent has been dequeued
		// Althoug 1 here makes sense, empirically seems that 2 is the minimum
		while (diff_wrap(firstTx32, ctx->firstTx) > 2)
		{
			hr = SoraURadioTxFree(TARGET_RADIO_TX, ctx->BufID[ctx->firstTx % cmd_fifo_queue_size]);
			ctx->firstTx++;
		}

		/*
		// Indeed, it never happened so removed to speed up the code
		if (lastTx32 != ctx->lastTx)
		{
			printf("This should not happen!\n");
		}
		*/

// For some reason we cannot read Sora from this thread, as timing collapses. Didn't spend much time investigating this issue.
/*
#ifdef READ_IN_WORKER_THREAD
		readSoraAndQueue();
#endif
*/

		cnt_rnd++;
	}

	ctx->TXRunning = false;

	return 0;
}