Exemplo n.º 1
0
COUNT SerialRead(char * buf, COUNT len)
{
        COUNT read = 0;
        COUNT readGeneration;
        BOOL wasFull = FALSE;

        do {
                IsrDisable(IRQ_LEVEL_SERIAL_READ);

                if ( RingBufferIsFull( &SerialInputRing ) ) {
                        wasFull = TRUE;
                }

                read = RingBufferRead(buf, len, &SerialInputRing);
                readGeneration = ReadGenerationCount;

                IsrEnable(IRQ_LEVEL_SERIAL_READ);

                if (read == 0) {
                        GenerationWait(&ReadGeneration, readGeneration, NULL);
                }
        } while (read == 0);

        // We were full, so lets make sure there wasn't any data buffered
        // in the hal.
        if ( wasFull ) {
                HalRaiseInterrupt( IRQ_LEVEL_SERIAL_READ );
        }
        return read;
}
Exemplo n.º 2
0
/** \brief a initialized packet
 *
 *  \warning Use *only* at init, not at packet runtime
 */
void PacketPoolStorePacket(Packet *p) {
    if (RingBufferIsFull(ringbuffer)) {
        exit(1);
    }

    RingBufferMrMwPut(ringbuffer, (void *)p);
    SCLogDebug("buffersize %u", RingBufferSize(ringbuffer));
}
Exemplo n.º 3
0
COUNT RingBufferWrite( char * buff, COUNT size, struct RING_BUFFER * ring )
{
	COUNT write = 0;
	while( write < size && !RingBufferIsFull( ring ) )
	{
		write += RingBufferWriteSmall( buff+write, size-write, ring );
		ring->Empty = FALSE;
	}
	return write;
}
Exemplo n.º 4
0
/** \brief a initialized packet
 *
 *  \warning Use *only* at init, not at packet runtime
 */
void PacketPoolStorePacket(Packet *p) {
    if (RingBufferIsFull(ringbuffer)) {
        exit(1);
    }

    /* Clear the PKT_ALLOC flag, since that indicates to push back
     * onto the ring buffer. */
    p->flags &= ~PKT_ALLOC;
    p->ReleasePacket = PacketPoolReturnPacket;
    PacketPoolReturnPacket(p);

    SCLogDebug("buffersize %u", RingBufferSize(ringbuffer));
}
Exemplo n.º 5
0
COUNT PipeReadInner( char * buff, COUNT size, PIPE_READ pipe ) {
        BOOL wasFull;
        BOOL dataLeft;
        COUNT read;

        //Acquire EmptyLock - No readers can progress until there is data.
        SemaphoreDown( & pipe->EmptyLock, NULL );

        //Acqure mutex lock - No one can do any io until
        //we leave the buffer.
        SemaphoreDown( & pipe->Mutex, NULL );

        //Check and see if the buffer is full.
        //If it is, then the FullLock should
        //have been leaked, and writers should be blocking.
        wasFull = RingBufferIsFull( & pipe->Ring );
        ASSERT( wasFull ? (pipe->FullLock.Count == 0) : TRUE );

        //Perform the read.
        read = RingBufferRead( buff, size, & pipe->Ring );
        // Ring is protected by a read lock which should prevent zero length reads.
        ASSERT( read > 0 );

        //See if the ring buffer is empty.
        //If it is then we need to leak the reader lock.
        dataLeft = !RingBufferIsEmpty( & pipe->Ring );

        //Release mutex lock - We are out of the ring, so
        //let other IO go if its already passed.
        SemaphoreUp( & pipe->Mutex );

        //If the ring was full while we have exclusive access,
        //and we  freed up some space then we should release
        //the writer lock so writers can go.
        if( wasFull && read > 0 ) {
                SemaphoreUp( & pipe->FullLock );
        }

        //If there is data left in the buffer, release the
        //empty lock so that other readers can go.
        //If there is no data in the buffer, we cant let
        //readers progress, so we leak the lock.
        if( dataLeft ) {
                SemaphoreUp( & pipe->EmptyLock );
        }
        return read;
}
Exemplo n.º 6
0
COUNT PipeWriteInner( char * buff, COUNT size, PIPE_WRITE pipe ) {
        BOOL wasEmpty;
        BOOL spaceLeft;
        COUNT write;

        //Acquire FullLock - No writers can progress until we are done.
        SemaphoreDown( & pipe->FullLock, NULL );

        //Acqure mutex lock - No one can do any io until
        //we leave the buffer.
        SemaphoreDown( & pipe->Mutex, NULL );

        //Check and see if the buffer is empty.
        //If it is, then the EmptyLock should
        //have been leaked, and readers should be blocking.
        wasEmpty = RingBufferIsEmpty( & pipe->Ring );
        ASSERT( wasEmpty ? (pipe->EmptyLock.Count == 0) : TRUE );

        //Perform the write.
        write = RingBufferWrite( buff, size, & pipe->Ring );
        // Ring is protected by a write lock which should prevent zero length writes.
        ASSERT( write > 0 );

        //See if the ring buffer is empty.
        //If it is then we need to leak the reader lock.
        spaceLeft = !RingBufferIsFull( & pipe->Ring );

        //Release mutex lock - We are out of the ring, so
        //let other IO go if its already passed.
        SemaphoreUp( & pipe->Mutex );

        //If the ring was empty while we have exclusive access,
        //and we wrote some data, then we should release
        //the EmptyLock so readers can go.
        if( wasEmpty && write > 0 ) {
                SemaphoreUp( & pipe->EmptyLock );
        }

        //If there is space left in the buffer, release the
        //FullLock so that other writers can go.
        //If there is no space in the buffer, we cant let
        //writers progress, so we leak the lock.
        if( spaceLeft ) {
                SemaphoreUp( & pipe->FullLock );
        }
        return write;
}
Exemplo n.º 7
0
void GetBytesInterrupt(void)
{
        while (!RingBufferIsFull(&SerialInputRing)) {
                char data;
                if (HalSerialGetChar(&data)) {
                        ASSUME(RingBufferWrite(&data, sizeof(data), &SerialInputRing), 1);
                } else {
                        break;
                }
        }

        if ( HandlerIsFinished(&ReadGenerationCritObject) ) {
                GenerationUpdateSafe(
                                &ReadGeneration,
                                ++ReadGenerationCount,
                                &ReadGenerationContext,
                                &ReadGenerationCritObject);
        }
}
Exemplo n.º 8
0
int main(void)
{
	InitClock();
	SerialInit();
	
	RingBufferInit(&location_buffer, 4, locations);
	
	PORTC.DIRSET = 0xF3;
	PORTE.DIRSET = 0xFF;
	PORTD.DIRSET = 0x33;
	PORTB.DIRCLR = 0xFF; /* PortB all inputs */
	
	/* Timers */
	//x_axis.step_timer = &TCC1;
	x_axis.pwm_timer = &TCC0;
	
	/* Limit Switches */
	x_axis.limit_switch_port = &PORTB;
	x_axis.limit_switch_mask = (1<<0); /* PORTB.0 */
	
	/* DIR ports (for inverting the stepper motor driver polarity) */
	x_axis.sign_select_port = &PORTC;
	x_axis.sign_switch_mask1 = 0x20; /* PORTC.5 */
	x_axis.sign_switch_mask2 = 0x10; /* PORTC.4 */
	
	/* PWM outputs: outputs will be 90 degrees out of phase */
	x_axis.phase_pwm_cmp1 = &(TCC0.CCB);
	x_axis.phase_pwm_cmp2 = &(TCC0.CCA);
	x_axis.compare_mask = TC0_CCBEN_bm | TC0_CCAEN_bm;
	
	/* Power Controls change the period: a longer period means longer off time and lower duty cycle */
	//x_axis.axis_idle_power = 60;
	x_axis.axis_run_power = 31;
	
	/* The minimum period of the PWM update timer/counter */
	/* Stepper motor tick period = 32 * min_period / 16000000 */
	//x_axis.min_period = 15;
	AxisInit (&x_axis);
	
	//y_axis.step_timer = &TCD1;
	y_axis.pwm_timer = &TCD0;
	y_axis.limit_switch_port = &PORTB;
	y_axis.limit_switch_mask  = (1<<1); /* PORTB.1 */
	y_axis.sign_select_port = &PORTD;
	y_axis.sign_switch_mask1 = 0x20;
	y_axis.sign_switch_mask2 = 0x10;
	y_axis.phase_pwm_cmp1 = &(TCD0.CCB);
	y_axis.phase_pwm_cmp2 = &(TCD0.CCA);
	y_axis.compare_mask = TC0_CCBEN_bm | TC0_CCAEN_bm;
	//y_axis.axis_idle_power = 60;
	y_axis.axis_run_power = 31;
	//y_axis.min_period = 15;
	AxisInit (&y_axis);
	
	//z_axis.step_timer = &TCE1;
	z_axis.pwm_timer = &TCE0;
	z_axis.limit_switch_port = &PORTB;
	z_axis.limit_switch_mask = (1<<2); /* PORTB.2 */
	z_axis.sign_select_port = &PORTE;
	z_axis.sign_switch_mask1 = 0x20; /* PORTE.5 */
	z_axis.sign_switch_mask2 = 0x10; /* PORTE.4 */
	z_axis.phase_pwm_cmp1 = &(TCE0.CCD);
	z_axis.phase_pwm_cmp2 = &(TCE0.CCC);
	z_axis.compare_mask = TC0_CCDEN_bm | TC0_CCCEN_bm;
	//z_axis.axis_idle_power = 60;
	z_axis.axis_run_power = 31; /* 33 unique waveform values: 0 (ground) to 33 (3.3v) */
	//z_axis.min_period = 15;
	AxisInit (&z_axis);

	PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
	
	// Fire up the timer for incrementing/decrementing steps
	TC0_t * step_timer = &TCC1;
	
	step_timer->CTRLB = TC_WGMODE_SS_gc;
	
	/* Overflow every 1 ms: 16Mhz / (64 * 250) = 1ms */						
	step_timer->PER = 250;
	step_timer->CTRLA = TC_CLKSEL_DIV64_gc;
	step_timer->CTRLFSET = TC_CMD_RESTART_gc;
	
	/* Enable the step overflow interrupt */
	step_timer->INTCTRLA |= TC_OVFINTLVL_LO_gc;
	// To Disable: axis->step_timer->INTCTRLA &= ~TC1_OVFINTLVL_gm;	
	
	
	char task = 0;
	sei();
	while(1)
    {
		//PORTE.OUTTGL = 0x02;
		
		//_delay_ms (10);
		
		//SerialData * s = SerialDataTransmitStruct();
		//if (s != 0)
		//{
		//	s->transmit_data[0] = 'a';
		//	s->transmit_data[1] = 'b';
		//	s->transmit_data[2] = 'c';
		//	SerialTransmit(s, 0x00, 3);
		//}
		
		SerialData * s = SerialDataAvailable();
		if (s != 0)
		{
			switch (s->receive_data[0])
			{
				case 0x88: // Reset everything (all axis back to limit switches)
				{
					task = TASK_LIMIT_SWITCH_Y;
					x_axis.state = 1;
					y_axis.state = 1;
					z_axis.state = 1;
					s->transmit_data[0] = 0x88;
					SerialTransmit (s, 0x00, 1); // Transmit to master device
					break;
				}
				case 0x77: // Ping (and location/status information)
				{
					s->transmit_data[0] = 0x77;
					
					// TODO: find a better way to do this
					step_timer->INTCTRLA &= ~TC1_OVFINTLVL_gm; // Disable the step timer
					int32_t x = AxisGetCurrentPosition(&x_axis);
					int32_t y = AxisGetCurrentPosition(&y_axis);
					int32_t z = AxisGetCurrentPosition(&z_axis);
					step_timer->INTCTRLA |= TC_OVFINTLVL_LO_gc; // Enable the step timer
					
					s->transmit_data[1] = x & 0xFF; x = x >> 8;
					s->transmit_data[2] = x & 0xFF; x = x >> 8;
					s->transmit_data[3] = x & 0xFF; x = x >> 8;
					s->transmit_data[4] = x & 0xFF;
					
					s->transmit_data[5] = y & 0xFF; y = y >> 8;
					s->transmit_data[6] = y & 0xFF; y = y >> 8;
					s->transmit_data[7] = y & 0xFF; y = y >> 8;
					s->transmit_data[8] = y & 0xFF;
					
					s->transmit_data[9] = z & 0xFF; z = z >> 8;
					s->transmit_data[10] = z & 0xFF; z = z >> 8;
					s->transmit_data[11] = z & 0xFF; z = z >> 8;
					s->transmit_data[12] = z & 0xFF;
					
					uint8_t status_bits = 0;
					if (IsMoving (&x_axis))
					{
						status_bits |= 0x01;
					}
					if (IsMoving (&y_axis))
					{
						status_bits |= 0x02;
					}
					if (IsMoving (&z_axis))
					{
						status_bits |= 0x04;
					}
					s->transmit_data[13] = status_bits;
					
					//step_timer->INTCTRLA &= ~TC1_OVFINTLVL_gm; // Disable the step timer
					buffer_lock = 1;
					s->transmit_data[14] = RingBufferCount(&location_buffer);
					buffer_lock = 0;
					//step_timer->INTCTRLA |= TC_OVFINTLVL_LO_gc; // Enable the step timer
					
					//s->transmit_data[14] = location_buffer_size;
					
					SerialTransmit (s, 0x00, 15); // Transmit to master device
					break;
				}
				case 0x32: // Set Position + Speed
				{
					Location_t l;
					
					/* Bytes 1:2 are time in milliseconds */
					l.time = decode_uint16_t(&(s->receive_data[1]));
					
					/* Bytes 3:14 are position */
					l.x = decode_uint32_t(&(s->receive_data[3]));
					l.y = decode_uint32_t(&(s->receive_data[7]));
					l.z = decode_uint32_t(&(s->receive_data[11]));
					
					// Add the new location to the buffer
					//step_timer->INTCTRLA &= ~TC1_OVFINTLVL_gm; // Disable the step timer
					
					buffer_lock = 1;
					if (!RingBufferIsFull(&location_buffer))
					{
						RingBufferAdd(&location_buffer, l);
					}
					//if (location_buffer_size < 1)
					//{
					//	nextLocation = l;
					//	location_buffer_size++;
					//}
					s->transmit_data[1] = RingBufferCount(&location_buffer);
					buffer_lock = 0;
					//step_timer->INTCTRLA |= TC_OVFINTLVL_LO_gc; // Enable the step timer
					
					s->transmit_data[0] = 0x32;
					//s->transmit_data[1] = location_buffer_size;
					SerialTransmit(s, 0x00, 2);
					break;
				}
			}
		}
		else if (task == TASK_LIMIT_SWITCH_Y)
		{
			uint8_t v = LimitSwitchHelper(&x_axis);
			v &= LimitSwitchHelper(&y_axis);
			v &= LimitSwitchHelper(&z_axis);
			if (v)
			{
				task = 0;
			}
		}
	}