/*This function is called on each interrupt. It reads the buffer, sets
the time for the next interrupt, and executes the action given in the
previous entry.*/
void StepperControl::interruptExec(){
	interruptCounter++; //Counting the interrupts. Currently serves no practical purpose (was used by older versions of this library).
	
	uint8_t exec = (uint8_t)(executionIndex%bufferSize); //Proper execution index based on buffer size.
	int bCheck = bufferCheck(1); //Buffer state.
	
	//As long as there is no waiting time given for the current task, but the buffer isn't empty, go to next task.
	while(taskList[1][exec] == 0 && bCheck){
		bCheck = bufferCheck(1);
		if(bCheck){
			++executionIndex;
		}else{
			--executionIndex;
		}
		exec = (uint8_t)(executionIndex%bufferSize);
	}
	
	//Adjusting values for new executionIndex.
	uint8_t exec1 = (uint8_t)(executionIndex-1);
	exec1 = exec1%bufferSize; //%bufferSize would be ignored it was added to the previous line. No idea, why.

	//If there are entries in the buffer, execute task from previous line (if there is anything to be done).
	if(bCheck){
		performTask(exec1);
	}
	
	//If the buffer underrun check failed, wait some time before trying again.
	if(!bCheck){
		++idleCounter; //Increase idle counter. This will be used in future versions to subtract the idle time from the next step, allowing more consistent movement.
		OCR1A = idleTime;
		return;
	}
	
	//If the time entries aren't empty, set new waiting time.
	//If the next task is further away than the timer would be able to count, wait for overflow and reduce overflow counter by 1.
	if(taskList[1][exec] > 2){
		--taskList[1][exec];
		OCR1A = 65535;
	}
	//If the next task is exactly as far as the timer would be able to count, set timer to max. value and move on to next entry.
	else if(taskList[1][exec] == 2 && taskList[0] == 0){
		taskList[1][exec] = taskList[1][exec]-2;
		OCR1A = 65535;
		++executionIndex;
	}
	//If the next task is due in less than the overflow time, set the timer to that time and move up to next entry.
	else if(taskList[1][exec] == 1 && taskList[0] > 0){
		OCR1A = taskList[0][exec];
		taskList[0][exec] = 0;
		--taskList[1][exec];
		++executionIndex;
	}
}
void VerilatedVcd::printStr (const char* str) {
    // Not fast...
    while (*str) {
	*m_writep++ = *str++;
	bufferCheck();
    }
}
void VerilatedVcd::fullFloat (vluint32_t code, const float newval) {
    (*((float*)&m_sigs_oldvalp[code])) = newval;
    // Buffer can't overflow; we have at least bufferInsertSize() bytes (>>>16 bytes)
    sprintf(m_writep, "r%.16g", (double)newval);
    m_writep += strlen(m_writep);
    *m_writep++=' '; printCode(code); *m_writep++='\n';
    bufferCheck();
}
Exemple #4
0
void SpTraceVcd::fullFloat (uint32_t code, const float newval) {
    (*((float*)&m_sigs_oldvalp[code])) = newval;
    // Buffer can't overflow before sprintf; we sized during declaration
    sprintf(m_writep, "r%.16g", (double)newval);
    m_writep += strlen(m_writep);
    *m_writep++=' '; printCode(code); *m_writep++='\n';
    bufferCheck();
}
/*Fills taskList until it's full. With current implementation it makes
sure that the list is really full when it stops the refilling, even if
some recently calculated values have been used already. This allows for
slightly longer independent execution of tasks in the interrupts, but
may cause an infinite loop, if the tasks are executed faster than new
tasks can be added. So make sure you have few enough motors that move
slowly enough.*/
void StepperControl::fillTaskList(uint16_t mask){
	uint16_t nextTimeAction = 0; //Each bit indicates a motor that will be moved after nextTaskTime.
	unsigned long nextTaskTime = 0; //Gives the amount of time before the next time something happens.
	int nextTaskTimeIndex = 0; //Index of the lowest value in nextStep that isn't 0.
	
	//Adds entries to the buffer as long as there is any space available.
	//If calculationIndex == executionIndex, means that the execution has caught up with the calculation.
	//If that is the case, bufferCheck() will return 0, but the calculation has to continue.
	while(bufferCheck() || calculationIndex == executionIndex){
		//Calculate the time until next step for each motor that is moved now.
		for(int i = 0; i < motorsCount; i++){
			if(nextStep[i] <= minimumTimerInterval && !(mask & (1 << i))) calculateNextStepTime(i, nextStep);
		}
		
		nextTaskTimeIndex = arrayMin(nextStep, motorsCount, minimumTimerInterval);
		if(nextTaskTimeIndex == -1) mask = 0xFFFF; //If there is no movement to be done, set mask to disable all motors.
		else nextTaskTime = nextStep[nextTaskTimeIndex];
		
		//Adding the time values to the buffer.
		if(mask != 0xFFFF){
			taskList[0][calculationIndex%bufferSize] = nextTaskTime%0x10000; //Remaining time after all overflows are done.
			taskList[1][calculationIndex%bufferSize] = (nextTaskTime/0x10000)+1; //Timer overflow count +1.
		}
		
		//Subtracts the previously determined lowest time before next step from the waiting time of each motor.
		//For each motor that reached minimumTimerInterval (has to be moved at this time), the nextTimeAction flag is set to 1.
		nextTimeAction = 0; //Resetting the action.
		for(int i = 0; i < motorsCount; i++){
			if(nextStep[i] > minimumTimerInterval) nextStep[i] -= nextTaskTime;
			if(nextStep[i] <= minimumTimerInterval && !(mask & (1 << i))){
				stepsCounterCalc++;
				nextTimeAction |= (1 << i);
			}
		}
		
		//Copying action flags to the buffer.
		taskList[2][calculationIndex%bufferSize] = nextTimeAction;
		
		//Debug output.
		/*Serial.print(calculationIndex);
		Serial.print(" ");
		Serial.print(executionIndex);
		Serial.print(" ");
		Serial.print(taskList[0][calculationIndex%bufferSize]);
		Serial.print(" ");
		Serial.print(taskList[1][calculationIndex%bufferSize]);
		Serial.print(" ");
		Serial.println(taskList[2][calculationIndex%bufferSize]);*/
		
		calculationIndex++;
	}
}
Exemple #6
0
int main(void)
{
	SetupHardware();
	CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream);
	GlobalInterruptEnable();

	_delay_ms(5000);
	uart_puts("ATI\r");
	_delay_ms(500);

	numbers = eeprom_read_word(( uint16_t *)1);

	for (;;)
	{
		if(ConfigSuccess)
		{
			int16_t b = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);

			if(b > -1)
			{
				if(b == '*')
				{
					iRead = 0;
				}

				if(b == '\r' || b == 0x1A)
				{
					uart_puts("\",129,\"aa\"\r");
					_delay_ms(300);
					bufferLength = 1;

					fputs("ok\r\n", &USBSerialStream);
				}

				if(b == 0x1A)
				{
					if(numbers > iRead)
						pb_clear(iRead +1, numbers);

					numbers = iRead;
					eeprom_write_word((uint16_t*)1, (uint16_t)numbers);
				}

				if(b == '*' || b == '\r')
				{
					iRead++;
					uart_puts("AT+CPBW=");

					char buff[5];
					itoa(iRead, buff, 10);
					uart_puts(buff);
					uart_puts(",\"+48");
				}

				if(b > 47 && b < 58)
				{
					uart_put(b);
				}

				if(b == 0x1B)
					openGate();

				if(b == 'd')
					bDebug = !bDebug;

			}

			CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
			USB_USBTask();
		}
		bufferCheck();

		if(!(PINC && (1 << PC2)))
			PORTB |= (1 << PB5);
		else
			PORTB &= ~(1 << PB5);
	}
}
void ExternalOutput::writeVideoData(char* buf, int len) {
    RtpHeader* head = reinterpret_cast<RtpHeader*>(buf);

    uint16_t currentVideoSeqNumber = head->getSeqNumber();
    if (currentVideoSeqNumber != lastVideoSequenceNumber_ + 1) {
        // Something screwy.  We should always see sequence numbers incrementing monotonically.
        ELOG_DEBUG("Unexpected video sequence number; current %d, previous %d",
                  currentVideoSeqNumber, lastVideoSequenceNumber_);
        // Set our search state to look for the start of a frame, and discard what we currently have (if anything).
        // it's now worthless.
        vp8SearchState_ = lookingForStart;
        unpackagedSize_ = 0;
        unpackagedBufferpart_ = unpackagedBuffer_;
    }

    lastVideoSequenceNumber_ = currentVideoSeqNumber;

    if (first_video_timestamp_ == -1) {
        first_video_timestamp_ = head->getTimestamp();
    }

    // TODO(pedro) we should be tearing off RTP padding here, if it exists.  But WebRTC currently does not use padding.

    RtpVP8Parser parser;
    erizo::RTPPayloadVP8* payload = parser.parseVP8(reinterpret_cast<unsigned char*>(buf + head->getHeaderLength()),
                                                    len - head->getHeaderLength());

    bool endOfFrame = (head->getMarker() > 0);
    bool startOfFrame = payload->beginningOfPartition;

    bool deliver = false;
    switch (vp8SearchState_) {
    case lookingForStart:
      if (startOfFrame && endOfFrame) {
        // This packet is a standalone frame.  Send it on.  Look for start.
        unpackagedSize_ = 0;
        unpackagedBufferpart_ = unpackagedBuffer_;
        if (bufferCheck(payload)) {
          memcpy(unpackagedBufferpart_, payload->data, payload->dataLength);
          unpackagedSize_ += payload->dataLength;
          unpackagedBufferpart_ += payload->dataLength;
          deliver = true;
        }
      } else if (!startOfFrame && !endOfFrame) {
        // This is neither the start nor the end of a frame.  Reset our buffers.  Look for start.
        unpackagedSize_ = 0;
        unpackagedBufferpart_ = unpackagedBuffer_;
      } else if (startOfFrame && !endOfFrame) {
        // Found start frame.  Copy to buffers.  Look for our end.
        if (bufferCheck(payload)) {
          memcpy(unpackagedBufferpart_, payload->data, payload->dataLength);
          unpackagedSize_ += payload->dataLength;
          unpackagedBufferpart_ += payload->dataLength;
          vp8SearchState_ = lookingForEnd;
        }
      } else {  // (!startOfFrame && endOfFrame)
        // We got the end of a frame.  Reset our buffers.
        unpackagedSize_ = 0;
        unpackagedBufferpart_ = unpackagedBuffer_;
      }
      break;
    case lookingForEnd:
      if (startOfFrame && endOfFrame) {
        // Unexpected.  We were looking for the end of a frame, and got a whole new frame.
        // Reset our buffers, send this frame on, and go to the looking for start state.
        vp8SearchState_ = lookingForStart;
        unpackagedSize_ = 0;
        unpackagedBufferpart_ = unpackagedBuffer_;
        if (bufferCheck(payload)) {
          memcpy(unpackagedBufferpart_, payload->data, payload->dataLength);
          unpackagedSize_ += payload->dataLength;
          unpackagedBufferpart_ += payload->dataLength;
          deliver = true;
        }
      } else if (!startOfFrame && !endOfFrame) {
        // This is neither the start nor the end.  Add it to our unpackage buffer.
        if (bufferCheck(payload)) {
          memcpy(unpackagedBufferpart_, payload->data, payload->dataLength);
          unpackagedSize_ += payload->dataLength;
          unpackagedBufferpart_ += payload->dataLength;
        }
      } else if (startOfFrame && !endOfFrame) {
        // Unexpected.  We got the start of a frame.  Clear out our buffer, toss this payload in,
        // and continue looking for the end.
        unpackagedSize_ = 0;
        unpackagedBufferpart_ = unpackagedBuffer_;
        if (bufferCheck(payload)) {
          memcpy(unpackagedBufferpart_, payload->data, payload->dataLength);
          unpackagedSize_ += payload->dataLength;
          unpackagedBufferpart_ += payload->dataLength;
        }
      } else {  // (!startOfFrame && endOfFrame)
        // Got the end of a frame.  Let's deliver and start looking for the start of a frame.
        vp8SearchState_ = lookingForStart;
        if (bufferCheck(payload)) {
          memcpy(unpackagedBufferpart_, payload->data, payload->dataLength);
          unpackagedSize_ += payload->dataLength;
          unpackagedBufferpart_ += payload->dataLength;
          deliver = true;
        }
      }
      break;
    }

    delete payload;

    this->initContext();
    if (video_stream_ == NULL) {
      // could not init our context yet.
      return;
    }

    if (deliver) {
      unpackagedBufferpart_ -= unpackagedSize_;

      long long currentTimestamp = head->getTimestamp();  // NOLINT
      if (currentTimestamp - first_video_timestamp_ < 0) {
        // we wrapped.  add 2^32 to correct this.
        // We only handle a single wrap around since that's ~13 hours of recording, minimum.
        currentTimestamp += 0xFFFFFFFF;
      }

      // All of our video offerings are using a 90khz clock.
      long long timestampToWrite = (currentTimestamp - first_video_timestamp_) /  // NOLINT
                                                (90000 / video_stream_->time_base.den);

      // Adjust for our start time offset

      // in practice, our timebase den is 1000, so this operation is a no-op.
      timestampToWrite += video_offset_ms_ / (1000 / video_stream_->time_base.den);

      AVPacket avpkt;
      av_init_packet(&avpkt);
      avpkt.data = unpackagedBufferpart_;
      avpkt.size = unpackagedSize_;
      avpkt.pts = timestampToWrite;
      avpkt.stream_index = 0;
      av_interleaved_write_frame(context_, &avpkt);   // takes ownership of the packet
      unpackagedSize_ = 0;
      unpackagedBufferpart_ = unpackagedBuffer_;
    }
}
Exemple #8
0
/**
 * @brief	Application main function
 * @return	Does not return
 * @note	This function will not return
 */
int main(void)
{
	uint32_t i;
	uint8_t repeat_num = UART_TEST_REPEAT_NUMBER;
	volatile int j = 1;
	uint8_t ch = 0;
	uint32_t IntStatus;

	/* Generic Initialization */
	Board_Init();

	Board_LED_Set(0, false);

	/* Disable UART1 IRQ */
	NVIC_DisableIRQ(UART1_IRQn);

	/* Initialize the UARTs */
	App_UART_Init(LPC_USART0);
	App_UART_Init(LPC_USART1);

	/* Custom Initialization */
	Chip_UART_IntEnable(LPC_USART1, RXRDY_INT, DISABLE);
	Chip_UART_IntEnable(LPC_USART1, TXRDY_INT, DISABLE);
	NVIC_EnableIRQ(UART1_IRQn);

	/* Data transfer loop */
	while (repeat_num--) {

		bufferInit(repeat_num);

		/* Sending from UART0 (polling mode) to UART1 (interrupt mode) */
		receiveCompleted = false;
		Chip_UART_IntEnable(LPC_USART1, RXRDY_INT, ENABLE);
		for (i = 0; i < BUFFER_SIZE; i++) {
			while (Chip_UART_SendByte(LPC_USART0, TxBuf0[i]) != SUCCESS) {}
		}
		while (!receiveCompleted) {}

        /* Clear Rx FIFO */
		Chip_UART_ReceiveByte(LPC_USART0, &ch);

		/* Sending from UART1 (interrupt mode) to UART0 (polling mode) */
		sendCompleted = false;
		Chip_UART_IntEnable(LPC_USART1, TXRDY_INT, ENABLE);
		for (i = 0; i < BUFFER_SIZE; i++) {
			while (Chip_UART_ReceiveByte(LPC_USART0, &RxBuf0[i]) != SUCCESS) {}
		}
		while (!sendCompleted) {}

		bufferCheck();
	}

	NVIC_DisableIRQ(UART1_IRQn);

	/* Test OK - Turn on Red LED */
	Board_LED_Set(0, true);

	/* Should not return */
	while (j) {}

	return 0;
}