示例#1
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);
}
示例#2
0
文件: dot11atx.c 项目: PaulJing/Sora
void Dot11ATxApp(const Config& config)
{
    SampleBufferSize = _M(2);
    SampleBuffer = SoraUAllocBuffer(SampleBufferSize);
	printf("tx buffer: %08x\n", SampleBuffer);
	printf("tx buffer size: %08x\n", SampleBufferSize);
	if (SampleBuffer == NULL) return;

	PreparePacket(config, (PVOID)SampleBuffer, (ULONG)SampleBufferSize);

    HRESULT hr;
	do
	{
		//Generate Signal
		hr = BB11ATxFrameMod(&TxVector, &Packet);
		printf("GenSignal return %08x\n", hr);
		printf("Signal bytes = %d\n", Packet.Reserved3);

        /*{
            PCOMPLEX8 pSampleBuffer = (PCOMPLEX8)SampleBuffer;
            for (i = 0; i < Packet.Reserved3; i++)
                printf("(%5d, %5d)\t", pSampleBuffer[i].re, pSampleBuffer[i].im);
            printf("\n");
        }*/

		hr = SoraURadioTransferEx(TARGET_RADIO, SampleBuffer, Packet.Reserved3, &TxID);
		printf("transfer, hr=%08x, id=%d\n", hr, TxID);
        FAILED_BREAK(hr);

        Monitor monitor;
        TxContext ctx(config, monitor);
        HANDLE hTxThread = AllocStartThread(DoDot11ATx, &ctx);

		if (SUCCEEDED(hr) && hTxThread)
		{
            printf("\n\nPress any key to exit the program\n");			
            time_t start = time(NULL);
	        while(!_kbhit())
            {
                if (config.Interval() != 0 && difftime(time(NULL), start) >= config.Interval()) break;
	        }

            StopFreeThread(hTxThread);
			hr = SoraURadioTxFree(TARGET_RADIO, TxID);
			printf("tx free return %08x\n", hr);
		}
	} while (FALSE);

	SoraUReleaseBuffer((PVOID)SampleBuffer);
	printf("unmap tx buffer ret: %08x\n", hr);

	printf("Tx out.\n");
}
示例#3
0
文件: Send.cpp 项目: PaulJing/Sora
HRESULT UmxSender::Deinit()
{
	if (!initialized)
		return -1;

	HRESULT hr = -1;
	HRESULT ret = S_OK;

	if (transferAllocated)
	{
		hr = SoraURadioTxFree(Radio::Current()->GetRadioNum(), txID);
		logger->Log(LOG_FUNC_CALL, L"SoraURadioTxFree called for radio %d\r\n", Radio::Current()->GetRadioNum());
		if (FAILED(hr))
		{
			logger->Log(LOG_ERROR, L"Failed. ret = %x\r\n", hr);
			ret = -1;
		}
		else
		{
			logger->Log(LOG_SUCCESS, L"success\r\n");
			txID = -1;
		}
		transferAllocated = false;
	}

	if (sampleBuf)
	{
		hr = SoraURadioUnmapTxSampleBuf(Radio::Current()->GetRadioNum(), (PVOID)sampleBuf);
		logger->Log(LOG_FUNC_CALL, L"SoraURadioUnmapTxSampleBuf called for radio %d\r\n", Radio::Current()->GetRadioNum());
		if (FAILED(hr))
		{
			logger->Log(LOG_ERROR, L"Failed. ret = %x\r\n", hr);		
			ret = -1;
		}
		else
		{
			logger->Log(LOG_SUCCESS, L"success\r\n");
			sampleBuf = 0;
		}
	}

	initialized = false;

	return ret;
}
示例#4
0
void Dot11BTxApp(const Config& config)
{
	HRESULT hr;

	if (Dot11BTxInit() < 0)
		return;

	Dot11BPreparePacket(config, (PVOID)SampleBuffer, (ULONG)SampleBufferSize);

	do
	{
		// Generate Signal
		hr = BB11BPMDPacketGenSignal(&Packet, &TxVector, (PUCHAR)TempBuffer, TempBufferSize);
		printf("[dot11b:tx] GenSignal return %08x\n", hr);
        printf("[dot11b:tx] Signal bytes=%d\n", Packet.Reserved3);

		hr = SoraURadioTransferEx(TARGET_RADIO, SampleBuffer, Packet.Reserved3, &TxID);
		printf("[dot11b:tx] transfer, hr=%08x, id=%d\n", hr, TxID);
        FAILED_BREAK(hr);

        Monitor monitor;
        TxContext ctx(config, monitor);
        HANDLE hTxThread = AllocStartThread(DoDot11BTx, &ctx);

		if (SUCCEEDED(hr))
		{
            printf("\n\nPress any key to exit the program\n");
            time_t start = time(NULL);
	        while(!_kbhit())
            {
                if (config.Interval() != 0 && difftime(time(NULL), start) >= config.Interval()) break;
	        }

            StopFreeThread(hTxThread);

			hr = SoraURadioTxFree(TARGET_RADIO, TxID);
			printf("[dot11b:tx] tx free return %08x\n", hr);
		}
	} while(false);

	Dot11BTxClean();

	printf("[dot11b:tx] Tx out.\n");
}
示例#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;
}