Welcome, Guest. Please Login.
Surveyor Corporation Surveyor SRV-1
Home Help Search Login

Surveyor Robotics Forum

Welcome to the user support forum for Surveyor SRV-1 robots, SRV-1 robot controllers and SVS stereo vision systems. To register for this forum, please send an email to support@surveyor.com which includes your desired forum user name, your registration email address, and a brief explanation of why you wish to join, and we will create a forum account for you.

Please note that there is a Search button in the forum toolbar for forum topics. Another effective search method for the entire surveyor.com site is to use Google, e.g. "xyz site://www.surveyor.com" where "xyz" is the search topic.



Pages: 1 2 
Send Topic Print
UART interrupts (Read 6822 times)
Tiush
YaBB Newbies
*




Posts: 11
UART interrupts
07/13/09 at 5:28am
 
Hi everyone,
 
I'm trying to add a buffer to the uart into the surveyor firmware. I looked over the internet, and I found someone who made it using interrupts. Inspired by his code I modified my uart.c and uart.h files:
 
uart.c
Code:
void init_uart0(void)
{
    *pPORTF_FER |= 0x0003;  // enable UART0 pins

    *pUART0_GCTL = UCEN;
    *pUART0_LCR = DLAB;
    *pUART0_DLL = UART0_DIVIDER;
    *pUART0_DLH = UART0_DIVIDER >> 8;
    *pUART0_LCR = WLS(8); // 8 bit, no parity, one stop bit
    
    //*************************************************************** MODIFIED CODE

        // Enable UART interrupts
	*pUART0_IER |= (ERBFI | ELSI);

	// Set uart_ISR as IVG10 handler
	*pEVT10 = (void*)uart_int;

	// Unmask IVG10 interrupt
	*pIMASK |= EVT_IVG10;

	// Unmask UART interrupts
	*pSIC_IMASK |= (IRQ_DMA8 | IRQ_DMA9);

    //***************************************************************

    // dummy reads to clear possible pending errors / irqs
    char dummy = *pUART0_RBR;
    dummy = *pUART0_LSR;
    dummy = *pUART0_IIR;
    SSYNC;
}

void uart_int() 
{
    char idr;

    idr = *pUART0_IIR;

    printf("uart interrupt : %c\n\r",idr);
}

( ... )
 


 
uart.h
Code:
void init_uart0();
void init_uart1();

void uart_int() __attribute__((interrupt_handler));
( ... )
 


 
But it doesn't work.... Maybe I forgot something to enable the interrupts....
 
If anyone knows how interrupts work on the surveyor, thank you for your help.
( Sorry for my poor english, I'm a french student... )
Back to top
 
 
  IP Logged
admin
YaBB Administrator
*****




Posts: 3676
Re: UART interrupts
Reply #1 - 07/13/09 at 8:17am
 
I haven't worked with any interrupt code, but one of our users started a project with interrupt-based processing for UART and camera.  The project has been inactive for a while, but it might give you some ideas.  Take a look at -
    http://code.google.com/p/srv-1-ce/
Back to top
 
 

SRV-1 Development Team
Surveyor Corporation
Email WWW   IP Logged
Tiush
YaBB Newbies
*




Posts: 11
Re: UART interrupts
Reply #2 - 07/13/09 at 10:34am
 
Actually, this is where I found the code I added to the srv1 firmware.  
But I think I missed something in the current firmware that disable the interrupt...
Back to top
 
 
  IP Logged
admin
YaBB Administrator
*****




Posts: 3676
Re: UART interrupts
Reply #3 - 07/13/09 at 12:01pm
 
You might look in init.c
Back to top
 
 

SRV-1 Development Team
Surveyor Corporation
Email WWW   IP Logged
Bolo
Junior Member
**




Posts: 59
Re: UART interrupts
Reply #4 - 08/15/09 at 10:25am
 
Tiush,
  Please keep us updated on your progress.   I might have a use for this as well.
 
  Bolo
Back to top
 
 

"People make problem. Trust me...Drone better"
Ivan Vanko -- IronMan 2
  IP Logged
Bolo
Junior Member
**




Posts: 59
Re: UART interrupts
Reply #5 - 08/15/09 at 8:18pm
 
Tiush,
    I also tried the code that you posted above,  and it does not work for me either.  I dumped the values of *pUART0_IER,*pIMASK, and *pSIC_IMASK, and it looks like the correct bits are being set to enable interrupts on uart0.   And they don't seem to change after repeated calls of other commands I have in myfunc(), so the registers are not being overwritten anywhere.
 
The interrupt scheme on the Blackfin is a bit complex, but I can't see anything that we are missing.  I looked at init.c, but it is not clear to me how that impacts anything.
 
  Bolo

 
 
 
Back to top
 
 

"People make problem. Trust me...Drone better"
Ivan Vanko -- IronMan 2
  IP Logged
Bolo
Junior Member
**




Posts: 59
Re: UART interrupts
Reply #6 - 08/30/09 at 6:45pm
 

Well, I got interrupts working on uart0.  I now tag motor commands by bracketing them with '[' and ']' so they can be processed immediately from the interrupt service routine when the ']' is received.   That way, the updates to the motor PWM timers can take place even in the middle of the encoding or transmission of an image.  The polling of the joystick inputs can now go at a 20ms update interval and the SRV1 responds more like an RC car does, even at the higher image sizes.  I don't see any noticeable change in the image update rates from doing this.
 
Unfortunately, this still requires use of the small memory model with bftiny.x and startup.asm.  I hate to shut myself off from the latest additions to the firmware and all the cool new functionality that needs the SDRAM space to run.
 
Now that I am comfortable with the process of loading srv1.ldr.recovery when I hose the firmware, I guess I will try again to get interrupts working with latest firmware using init.c.    
 
Bolo
Back to top
 
« Last Edit: 08/30/09 at 6:46pm by Bolo »  

"People make problem. Trust me...Drone better"
Ivan Vanko -- IronMan 2
  IP Logged
Tiush
YaBB Newbies
*




Posts: 11
Re: UART interrupts
Reply #7 - 09/03/09 at 2:36am
 
Hi Bolo,  
Sorry if I didn't answer to your questions before, but I was busy with an other project and didn't see your posts...
It seems that you find a solution for the interrupts, could you please explain how?
Thank you!
 
TiuSh
Back to top
 
 
  IP Logged
Bolo
Junior Member
**




Posts: 59
Re: UART interrupts
Reply #8 - 09/03/09 at 10:02am
 

Quote from Tiush on 09/03/09 at 2:36am:
Hi Bolo,
Sorry if I didn't answer to your questions before, but I was busy with an other project and didn't see your posts...
It seems that you find a solution for the interrupts, could you please explain how?
Thank you!

TiuSh

 
You will need to use the earlier version of the firmware that uses startup.asm, found here
 
http://www.surveyor.com/blackfin/srv-blackfin-050608.zip
 
With that firmware, the interrupt code you posted at the beginning of this thread will work.
 
Soon I hope to figure out how to get interrupts working with the later firmware.
 
 
   Bolo
Back to top
 
 

"People make problem. Trust me...Drone better"
Ivan Vanko -- IronMan 2
  IP Logged
Bolo
Junior Member
**




Posts: 59
Re: UART interrupts
Reply #9 - 09/03/09 at 8:22pm
 
Oh, and if you do drop back to the earlier firmware to try the interrupts, you might want to grab the setPWM() function from the later versions, as there was a bug documented here:
 
http://www.surveyor.com/cgi-bin/yabb2/YaBB.pl?num=1230073856/1#1
 
The bug only manifested for me because I am implementing a car-steering mode for an RC car chassis.  
 
Bolo
Back to top
 
 

"People make problem. Trust me...Drone better"
Ivan Vanko -- IronMan 2
  IP Logged
Tiush
YaBB Newbies
*




Posts: 11
Re: UART interrupts
Reply #10 - 09/04/09 at 7:21am
 
Quote from Bolo on 09/03/09 at 10:02am:
You will need to use the earlier version of the firmware that uses startup.asm, found here

http://www.surveyor.com/blackfin/srv-blackfin-050608.zip

With that firmware, the interrupt code you posted at the beginning of this thread will work.

Soon I hope to figure out how to get interrupts working with the later firmware.


  Bolo


It seems to work, but I can't read the characters on the uart0...
Could you post your "uart.c" file please... Thank you for your precious help Bolo!
 
TiuSh
Back to top
 
« Last Edit: 09/04/09 at 7:32am by Tiush »  
  IP Logged
Bolo
Junior Member
**




Posts: 59
Re: UART interrupts
Reply #11 - 09/04/09 at 8:41am
 
Sure.  Here is uart.h.  The top section is what I added, bottom is stock code
 
Code:
// uart.h for uart0 interrupt-driven option
//

#ifndef UART_H_
#define UART_H_

#define SSYNC    asm("ssync;")


#define RX_BUFF_SIZE	1024
#define PRIORITY_BUFF_SIZE	16
#define RTS_ASSERT			*pPORTHIO_CLEAR	= PH6;
#define RTS_DEASSERT		*pPORTHIO_SET	= PH6;
#define CTS_TRIGGERED		(*pPORTHIO & PH0)
#define CTS_CLEAR_TRIGGER	*pPORTHIO_CLEAR = PH0;
#define disable_interrupts(x)	asm volatile("cli %0" : "=r"(x))
#define enable_interrupts(x)	asm volatile("sti %0" : : "r"(x))
#define UART0_INTERRUPTS_ENABLED  ((*pUART0_IER & ERBFI)== 1)
#define PRIORITY_COMMAND_HEADER '['
#define PRIORITY_COMMAND_TRAILER ']'

void uart0_init_interruptable();
void uart0_disable_interrupts();
unsigned char uart0GetBufferCharWait(unsigned char *data);
unsigned char uart0GetBufferCharNoWait(unsigned char *data);
void uart0_ISR()	__attribute__((interrupt_handler));

//----------------------------------------------------------------

void init_uart0();
void init_fast_uart();
void init_uart1();

void uart0SendChar(unsigned char s);
void uart0SendString(unsigned char *s);
void uart0SendChars(unsigned char *s, unsigned int count);
unsigned char uart0GetCh();
unsigned char uart0GetChar(unsigned char *s);
void uart1SendChar(unsigned char s);
void uart1SendString(unsigned char *s);
void uart1SendChars(unsigned char *s, unsigned int count);
unsigned char uart1GetCh();
unsigned char uart1GetChar(unsigned char *s);
void printNumber(unsigned char base, unsigned char noDigits, unsigned char sign, unsigned char pad, unsigned int number);

#endif /* UART_H */

 


 
Back to top
 
 

"People make problem. Trust me...Drone better"
Ivan Vanko -- IronMan 2
  IP Logged
Bolo
Junior Member
**




Posts: 59
Re: UART interrupts
Reply #12 - 09/04/09 at 8:44am
 
Here is uart.c (part 1 of 2).  Note that I am not using any hardware flow control on receiving data on uart0 even though the assert/de-assert defines are present in the header file.  So far, the interrupt-driven buffering seems to be fast enough that it is not needed.  I will post an update if this ever proves wrong.
Code:
//--------------------------------------------------------
// uart.c
//
//  This code was changed to add an interrupt-driven priority
//   command option for uart0, for immediate processing of commands
//   like motor and servo commands.  It depends upon the
//   startup.asm method of initialization, which uses the
//   SVG15 interrupt to put the processor into supervisor
//   mode while allowing other interrupts to occur.
//
//  Use myfunc commands to enable/disable interrupt-driven input to uart0. 
//   Use commands prefixed with [ and followed by ] to trigger immediate 
//   processing of the command within the interrupt service routine.  See myfunc.c for
//   code to process motor commands and servo commands in this manner.
//
#include <cdefBF537.h>
#include "config.h"
#include "uart.h"
#include "srv.h"
#include "print.h"

//-----------------------------------------
// Buffers for interrupt-enabled receive
//
volatile unsigned char rx_buff[RX_BUFF_SIZE];
volatile unsigned char *r_tail; // Ring buffer tail-pointer
volatile unsigned char *r_ptr; // Ring buffer read-pointer

volatile unsigned char priority_buff[PRIORITY_BUFF_SIZE];
volatile unsigned char *p_tail;
volatile unsigned char *p_ptr;

int temp3;
volatile char stop;
volatile char processing_priority_command;
//------------------------------------------

void init_uart0(void) {
	*pPORTF_FER |= 0x0003; // enable UART0 pins

	*pUART0_GCTL = UCEN;
	*pUART0_LCR = DLAB;
	*pUART0_DLL = UART0_DIVIDER;
	*pUART0_DLH = UART0_DIVIDER >> 8;
	*pUART0_LCR = WLS(8); // 8 bit, no parity, one stop bit

	// dummy reads to clear possible pending errors / irqs
	char dummy = *pUART0_RBR;
	dummy = *pUART0_LSR;
	dummy = *pUART0_IIR;
	SSYNC;
}

void init_fast_uart0(void) {
	*pPORTF_FER |= 0x0003; // enable UART0 pins

	*pUART0_GCTL = UCEN;
	*pUART0_LCR = DLAB;
	*pUART0_DLL = UART0_FAST_DIVIDER;
	*pUART0_DLH = UART0_FAST_DIVIDER >> 8;
	*pUART0_LCR = WLS(8); // 8 bit, no parity, one stop bit

	// dummy reads to clear possible pending errors / irqs
	char dummy = *pUART0_RBR;
	dummy = *pUART0_LSR;
	dummy = *pUART0_IIR;
	SSYNC;
}

void init_uart1(void) {
	*pPORTF_FER |= 0x000C; // enable UART1 pins
	*pUART1_GCTL = UCEN;
	*pUART1_LCR = DLAB;
	*pUART1_DLL = UART1_DIVIDER;
	*pUART1_DLH = UART1_DIVIDER >> 8;
	*pUART1_LCR = WLS(8); // 8 bit, no parity, one stop bit

	char dummy = *pUART1_RBR;
	dummy = *pUART1_LSR;
	dummy = *pUART1_IIR;
	SSYNC;
}

void uart0SendChar(unsigned char c) {
	while (*pPORTHIO & 0x0001) // hardware serial flow control -
		continue; //    S32 pin 17 should be grounded to disable
	while (!(*pUART0_LSR & THRE))
		continue;
	*pUART0_THR = c;
}

void uart0SendString(unsigned char *s) {
	char a;
	while ((a = *s++)) {
		uart0SendChar(a);
	}
}

void uart0SendChars(unsigned char *buf, unsigned int size) {
	while (size--) {
		uart0SendChar(*buf++);
	}
}
//-----------------------------------------------------------
// These functions have changed to accommodate both polled and
//    interrupt-driven receive
//
unsigned char uart0GetCh() // This one waits for input
{
	// if interrupts enabled, wait until something is in buffer
	//   and return it.

	if (UART0_INTERRUPTS_ENABLED) {
		unsigned char c;
		uart0GetBufferCharWait(&c);
		return c;
	}

	// if interrupts not enabled, wait for Data Ready bit, then
	//   get char and return it.

	while (!(*pUART0_LSR & DR))
		;
	return *pUART0_RBR;

}

unsigned char uart0GetChar(unsigned char *a) // this one does not wait
{
	// if interrupts enabled, check for something in buffer
	//   and return it.

	if (UART0_INTERRUPTS_ENABLED) {
		return uart0GetBufferCharNoWait(a);
	}

	// if interrupts not enabled, check Data Ready bit, if not set, return
	//   otherwise, get char and return it.

	if (!(*pUART0_LSR & DR))
		return 0;
	*a = *pUART0_RBR;
	return 1;
}

//-------------------------------------------------------------

void uart1SendChar(unsigned char c) {
	while (!(*pUART1_LSR & THRE))
		;
	*pUART1_THR = c;
}

void uart1SendString(unsigned char *s) {
	char a;
	while ((a = *s++)) {
		uart1SendChar(a);
	}
}

void uart1SendChars(unsigned char *buf, unsigned int size) {
	while (size--) {
		uart1SendChar(*buf++);
	}
}

unsigned char uart1GetCh() {
	while (!(*pUART1_LSR & DR))
		;
	return *pUART1_RBR;
}

unsigned char uart1GetChar(unsigned char *a) {
	if (!(*pUART1_LSR & DR))
		return 0;
	*a = *pUART1_RBR;
	return 1;
}

//---------------------------------------------------------------
// Bolo - functions to push and pull chars from ring buffers
//        Handles both regular mode and priority mode, using
//        separate buffers for each
//
unsigned char buff_receive_push(unsigned char *data) {
	disable_interrupts(temp3);
	if (processing_priority_command) {
		// Check for full buffer
		if (p_tail >= p_ptr) {
			if ((p_tail - p_ptr) >= PRIORITY_BUFF_SIZE - 1) {
				enable_interrupts(temp3);
				return (0);
			}
		} else {
			if ((p_tail + PRIORITY_BUFF_SIZE - p_ptr) >= PRIORITY_BUFF_SIZE - 1) {
				enable_interrupts(temp3);
				return (0);
			}
		}
		*p_tail = *data;
		// printf("<buffer push %c to %08x>", *p_tail, p_tail);
		p_tail++;

		/* Connect Ringbuffer head to tail */
		if (p_tail >= priority_buff + PRIORITY_BUFF_SIZE)
			p_tail = priority_buff;

	} else {
		// Check for full buffer
		if (r_tail >= r_ptr) {
			if ((r_tail - r_ptr) >= RX_BUFF_SIZE - 1) {
				enable_interrupts(temp3);
				return (0);
			}
		} else {
			if ((r_tail + RX_BUFF_SIZE - r_ptr) >= RX_BUFF_SIZE - 1) {
				enable_interrupts(temp3);
				return (0);
			}
		}
		*r_tail = *data;
		// printf("<buffer push %c to %08x>", *r_tail, r_tail);
		r_tail++;

		/* Connect Ringbuffer head to tail */
		if (r_tail >= rx_buff + RX_BUFF_SIZE)
			r_tail = rx_buff;
	}
	enable_interrupts(temp3);
	return (1);
}

unsigned char buff_receive_pull(unsigned char *data) {
	disable_interrupts(temp3);

	if (processing_priority_command) {

		// Check if there's any data in the buffer
		if (p_ptr == p_tail) {
			enable_interrupts(temp3);
			return (0);
		}
		*data = *p_ptr;
		//printf("<%c>", *data, p_ptr);

		p_ptr++;

		/* Connect head to tail of ringbuffer */
		if (p_ptr >= priority_buff + PRIORITY_BUFF_SIZE)
			p_ptr = priority_buff;


	} else {
		// Check if there's any data in the buffer
		if (r_ptr == r_tail) {
			enable_interrupts(temp3);
			return (0);
		}
		*data = *r_ptr;
		//printf("<%c>", *data, r_ptr);

		r_ptr++;

		/* Connect ringbuffer */
		if (r_ptr >= rx_buff + RX_BUFF_SIZE)
			r_ptr = rx_buff;

	}

	enable_interrupts(temp3);
	return (1);
}

void uart0_init_interruptable() {
	// printf("Initializing uart0 interrupts...");
	// Init ringbuffer pointers
	r_tail = rx_buff;
	r_ptr = rx_buff;
	p_tail = priority_buff;
	p_ptr = priority_buff;
	processing_priority_command = 0;

	// Enable UART interrupts on receive
	*pUART0_IER |= (ERBFI | ELSI);

	// Set uart_ISR as IVG10 handler
	*pEVT10 = (void*) uart0_ISR;

	// Unmask IVG10 interrupt
	*pIMASK |= EVT_IVG10;

	// Unmask UART interrupts
	*pSIC_IMASK |= (IRQ_DMA8);

}

unsigned char uart0GetBufferCharWait(unsigned char *data) {
	unsigned char c;
	// printf("GetBufferCharWait");
	// printf("r_ptr = %08x, r_tail = %08x", r_ptr, r_tail);
	while (UART0_INTERRUPTS_ENABLED && !buff_receive_pull(&c))
		;
	*data = c;
	// printf("<got %c>", *data);
	return 1;
}

unsigned char uart0GetBufferCharNoWait(unsigned char *data) {
	unsigned char c;
	// printf("GetBufferCharNoWait");
	if (!(r_ptr == r_tail)) {
		buff_receive_pull(&c);
		*data = c;
		// printf("<got %c>", *data);
		return 1;
	} else
		return 0;
}

void uart0_ISR() {
	unsigned char identification_register;

	identification_register = *pUART0_IIR;

	// Check to see if interrupt was caused by uart error
	//
	if (identification_register == 0x6) {
		// FIXME, atm just clears interrupt
		int temp3 = *pUART0_LSR;
		temp3++;
		return;
	}

	// Check to see if interrupt was caused by newly received data
	//
	if (identification_register == 0x4) {
		// Read data into ringbuffer
		unsigned char c = *pUART0_RBR;

		// Manage priority commands
		if (c == PRIORITY_COMMAND_HEADER) {
			processing_priority_command = 1;
			return;
		}
		if (c == PRIORITY_COMMAND_TRAILER) {
			myfunc();
			p_tail = priority_buff;
			p_ptr = priority_buff;
			processing_priority_command = 0;
			return;
		}
		buff_receive_push(&c);
		return;
	}
}

void uart0_disable_interrupts() {
	*pUART0_IER &= ~(ERBFI | ELSI);
}

 


Back to top
 
« Last Edit: 09/04/09 at 8:58am by Bolo »  

"People make problem. Trust me...Drone better"
Ivan Vanko -- IronMan 2
  IP Logged
Bolo
Junior Member
**




Posts: 59
Re: UART interrupts
Reply #13 - 09/04/09 at 8:48am
 
uart.c (part 2 of 2)  This is simply the printNumber() function, unchanged from stock.
 
Code:
/*****************************************************************************
 *
 * Description:
 *    Routine for printing integer numbers in various formats. The number is
 *    printed in the specified 'base' using exactly 'noDigits', using +/- if
 *    signed flag 'sign' is TRUE, and using the character specified in 'pad'
 *    to pad extra characters.
 *
 * Params:
 *    [in] base     - Base to print number in (2-16)
 *    [in] noDigits - Number of digits to print (max 32)
 *    [in] sign     - Flag if sign is to be used (TRUE), or not (FALSE)
 *    [in] pad      - Character to pad any unused positions
 *    [in] number   - Signed number to print
 *
 ****************************************************************************/
void printNumber(unsigned char base, unsigned char noDigits,
		unsigned char sign, unsigned char pad, unsigned int number) {
	static unsigned char hexChars[16] = "0123456789ABCDEF";
	unsigned char *pBuf;
	unsigned char buf[32];
	unsigned int numberAbs;
	unsigned int count;

	// prepare negative number
	if (sign && (number < 0))
		numberAbs = -number;
	else
		numberAbs = number;

	// setup little string buffer
	count = (noDigits - 1) - (sign ? 1 : 0);
	pBuf = buf + sizeof(buf);
	*--pBuf = '\0';

	// force calculation of first digit
	// (to prevent zero from not printing at all!!!)
	*--pBuf = hexChars[(numberAbs % base)];
	numberAbs /= base;

	// calculate remaining digits
	while (count--) {
		if (numberAbs != 0) {
			//calculate next digit
			*--pBuf = hexChars[(numberAbs % base)];
			numberAbs /= base;
		} else
			// no more digits left, pad out to desired length
			*--pBuf = pad;
	}

	// apply signed notation if requested
	if (sign) {
		if (number < 0)
			*--pBuf = '-';
		else if (number > 0)
			*--pBuf = '+';
		else
			*--pBuf = ' ';
	}

	// print the string right-justified
	uart0SendString(pBuf);
}


 

Back to top
 
 

"People make problem. Trust me...Drone better"
Ivan Vanko -- IronMan 2
  IP Logged
Bolo
Junior Member
**




Posts: 59
Re: UART interrupts
Reply #14 - 09/04/09 at 9:05am
 
Here is the code from myfunc.c that I use to turn interrupts on and off, and process motor commands.
This of course requires adding a % case in the switch statement in main.c, which was not present in the stock code
of 050608.

Code:
#include <cdefBF534.h>
#include "config.h"
#include "myfunc.h"
#include "print.h"
#include "uart.h"
#include "srv.h"

#define SSYNC    asm("ssync;")

extern int pwm1_init, pwm1_mode,lspeed, rspeed;

void myfunc() {
	unsigned char ch;
	ch = uart0GetCh();
	switch (ch) {
	case 'M': // Priority motor command
		priority_motor_command();
		break;
	case 'i': // set up interrupt handling on UART0 receive
		uart0_init_interruptable();
		printf("#i");
		// dump_interrupt_registers();
		break;
	case 'd':
		uart0_disable_interrupts();
		printf("#d");
		break;
	}
	return;
}

void priority_motor_command() {
	if (!pwm1_init) {
		initPWM();
		pwm1_init = 1;
		pwm1_mode = PWM_PWM;
		lspeed = rspeed = 0;
	}
	lspeed = (int) ((signed char) uart0GetCh());
	rspeed = (int) ((signed char) uart0GetCh());
	setPWM(lspeed, rspeed);
}
 

Back to top
 
 

"People make problem. Trust me...Drone better"
Ivan Vanko -- IronMan 2
  IP Logged
Pages: 1 2 
Send Topic Print