示例#1
0
void putintUSART( char *data)
{
    while(BusyUSART());
    putcUSART(*(data+1));
    while(BusyUSART());
    putcUSART(*data);

}
示例#2
0
文件: usart.c 项目: jeffhuys/IvIBot
void sendCommand(rom char *string) {
    while(*string) {
        putcUSART(*string);
        XLCDPut(*string);
        *string++;
    }
    putcUSART((char)13);
    XLCDPut((char)13);
}
示例#3
0
文件: usart.c 项目: jeffhuys/IvIBot
void putStrUSART(char *str) {
	int i = 0 ;
        XLCDClear();
	while ( str[i] ) {
            XLCDPut(str[i]);
            putcUSART(str[i++]);
        }
        putcUSART((char)13);
}
示例#4
0
/******************************************************************************
 * Function:        void sendReport(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          Send report to bleutooth client
 *
 * Side Effects:    Filed ReportData array not used by others
 *
 * Note:            To reduce space get rid of the ReportData array
 *                  (it is probably better).
 *****************************************************************************/
void sendReport(void) {
    int i = 0;
    BYTE *p;
    //report back the state of the ivibot register values
    ReportData[REP_PORTB] = PORTB; //0
    ReportData[REP_PORTD] = PORTD; //1
    ReportData[REP_PORTEC] = getPortEC(); //2

    ReportData[REP_AD0] = getAD0(); //3
    ReportData[REP_AD1] = getAD1(); //4
    ReportData[REP_AD2] = getAD2(); //5
    ReportData[REP_AD3] = getAD3(); //6

    ReportData[REP_PR2] = PR2; //7
    ReportData[REP_T2CON] = T2CON; //8
    ReportData[REP_CCP1] = CCP1CON; //9
    ReportData[REP_CCP2] = CCP2CON; //10
    ReportData[REP_CCPR1L] = stored_CCPR1L; //11 CCPR1L stored, it is not allowed to read the counting REG;
    ReportData[REP_CCPR2L] = stored_CCPR2L; //12 see CCPR1L above;

    ReportData[REP_PROTOCOL] = REP_PROTOCOLVERSION; //13
    ReportData[REP_TRISB] = TRISB; //14
    ReportData[REP_TRISD] = TRISD; //15

    p = (BYTE *) & SystemTime;
    ReportData[REP_SYSTEMMSTIMERL] = p[0]; // 16 Byte 0
    ReportData[REP_SYSTEMMSTIMERML] = p[1]; // 17 ,,  1
    ReportData[REP_SYSTEMMSTIMERMH] = p[2]; // 18 ,,  2
    ReportData[REP_SYSTEMMSTIMERH] = p[3]; // 19 ,,  3

    p = (BYTE *) & counter0;
    ReportData[REP_COUNTER0L] = p[0]; // 20 Byte 0
    ReportData[REP_COUNTER0ML] = p[1]; // 21 ,,  1
    ReportData[REP_COUNTER0MH] = p[2]; // 22 ,,  2
    ReportData[REP_COUNTER0H] = p[3]; // 23 ,,  3

    p = (BYTE *) & counter1;
    ReportData[REP_COUNTER1L] = p[0]; // 24 Byte 0
    ReportData[REP_COUNTER1ML] = p[1]; // 25 ,,  1
    ReportData[REP_COUNTER1MH] = p[2]; // 26 ,,  2
    ReportData[REP_COUNTER1H] = p[3]; // 27 ,,  3

    // Start with ascii ESC followed by 'AT' so the JAVA counterpart can sync
    putcUSART((char) 27);
    putcUSART((char) 'A');
    putcUSART((char) 'T');
	
    for (i = 0; i < 32; i++) { // Java bluetooth client expecte 32 BYTES only 28 used.
        //putcUSART('B') ;  // debug
        //putcUSART((char) i + '0');
        putcUSART(ReportData[i]);
    }
    putcUSART((char) 13); // Send a single newline, end of this report transmission.

}
示例#5
0
void main(void) {
    int count;
    int size;
    unsigned int adcValue = 0;
    unsigned int adcValueOld = 0;
    char buffer[16];

    ConfigureOscillator();
    InitApp();

    lcd_init();
    lcd_enable();
    lcd_cursor_off();
    lcd_test();
    lcd_pos(2, 1);
    while (1) {
        ConvertADC();
        while (BusyADC());
        adcValue = ReadADC();
        if (adcValue != adcValueOld) {
            lcd_clear();
            //Linha 1
            lcd_pos(1, 1);
            memset(&buffer[0], 0, sizeof (buffer));
            sprintf(&buffer[0], "Step:%.4u %3.1f%%", adcValue, ((float) adcValue / 1023) * 100);
            size = (strlen(buffer) > sizeof(buffer)) ? sizeof(buffer) : strlen(buffer);
            lcd_write_buffer(buffer, size);
            for(count = 0; count < size; count++){
                while(BusyUSART());
                putcUSART((char)buffer[count]);
            }
            //Linha 2
            lcd_pos(2, 1);
            memset(&buffer[0], 0, sizeof (buffer));
            sprintf(&buffer[0], "Volts:%1.7fV", (float)adcValue * ((float)5 /1023));
            size = (strlen(buffer) > sizeof(buffer)) ? sizeof(buffer) : strlen(buffer);
            lcd_write_buffer(buffer, size);
            //Variável de controle
            adcValueOld = adcValue;
            for(count = 0; count < size; count++){
                while(BusyUSART());
                putcUSART((char)buffer[count]);
            }
        }
        for (count = 0; count < 40; count++) {
            __delay_ms(10);
        }
    }
}
void Tx_Mensagem(unsigned char msg_serial){
	/*TXREG=msg_serial;
   	while(PIR1bits.TXIF==0);*/
	while(BusyUSART()); //Aguarda o final da transmissão 
	putcUSART(msg_serial);
	stdout = _H_USART;	
}
示例#7
0
void putsUSART( char *data)
{
  do
  {  // Transmit a byte
    while(BusyUSART());
    putcUSART(*data);
  } while( *data++ );
}
示例#8
0
void terminalTask() {
        if (DataRdyUSART()) {\
            while(BusyUSART());
            cmd = getcUSART();
            while(BusyUSART());
            putcUSART(cmd);
        }
    
        switch (cmd) {
        case '?':
            sendTerminalCommandList();
            break;
        case '1':
            terminalSendPString(TERMINAL_RETURN);
            terminalSendPString("Measuring carbon...");
            measureCarbon();
            terminalSendPString(TERMINAL_RETURN);
            updateTerminal();
            break;
        case '2':
            terminalSendPString(TERMINAL_RETURN);
            terminalSendPString("Measuring salinity...");
            measureSalinity();
            terminalSendPString(TERMINAL_RETURN);
            updateTerminal();
            break;
        case '3':
            terminalSendPString(TERMINAL_RETURN);
            terminalSendPString("Measuring flow rate...");
            measureFlowRate();
            terminalSendPString(TERMINAL_RETURN);
            updateTerminal();
            break;
        case '4':
            terminalSendPString(TERMINAL_RETURN);
            terminalSendPString("Measuring temperature...");
            measureTemperature();
            terminalSendPString(TERMINAL_RETURN);
            updateTerminal();
            break;
        case 'c':
            updateTerminal();
            break;
        case 'd':
            terminalSendPString(TERMINAL_RETURN);
            terminalSendPString("Revealing display");
            sendTerminalCommandLine();
            break;
        case 0xff:
            break;
        default:
            terminalSendPString(TERMINAL_RETURN);
            terminalSendPString("Invalid command");
            sendTerminalCommandLine();
        }
        cmd = 0xff;
}
示例#9
0
文件: env.c 项目: simait/TinyTimber
/**
 * \brief The PIC18 print function.
 *
 * C18 has some serious issue when it handles strings, especially constant
 * strings. They tend to end up in the rom and thus makes it impossible to
 * treat constants strings and other strings in the same way.
 */
void pic18_print(const rom char *msg)
{
	while (*msg)
	{
		while (BusyUSART());
		putcUSART(*msg++);
	}
	while (BusyUSART());
}
示例#10
0
void ProcessIO(void)
{	
	uchar i;
	BlinkUSBStatus();		//Blink	the	LEDs according to the USB device status
	// User	Application	USB	tasks
	if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1))	return;

	// only check	for	new	USB	buffer if the old RS232	buffer is
	// empty.	 This will cause additional	USB	packets	to be NAK'd

	// RS232_送信バッファに HostPC から届いたデータをFillする.
	if( mDataRdyUSART() < 32 ) 

	if (LastRS232Out == 0) {						  
		LastRS232Out = getsUSBUSART(RS232_Out_Data,64);	//until	the	buffer is free.
		if(LastRS232Out	> 0) {
//			RS232_Out_Data_Rdy = 1;	 //	signal buffer full
			RS232cp	= 0;  // Reset the current position
		}
	}

#if	USART_USE_TX_INTERRUPT		// 送信割り込みを使用する.
	//USARTが送信可であれば RS232_送信バッファの内容を USARTに 1文字送る.
	if(LastRS232Out && mTxRdyUSART())	{
//		PIR1bits.TXIF = 0;			// 送信割り込みフラグ.
		PIE1bits.TXIE = 1;			// 送信割り込み許可.
	}
#else
	//USARTが送信可であれば RS232_送信バッファの内容を USARTに 1文字送る.
	if(LastRS232Out && mTxRdyUSART())	{
		putcUSART(RS232_Out_Data[RS232cp]);	//1文字送る.
		++RS232cp;
		if (RS232cp	== LastRS232Out) {
//			RS232_Out_Data_Rdy = 0;
			LastRS232Out=0;
			RS232cp=0;
		}
	}
#endif

	//可能なら、RS232_受信バッファの内容をHostPCに送る.
	if((USBUSARTIsTxTrfReady())	&& (mDataRdyUSART())){
		i=0;
		while( mDataRdyUSART() ) {
			if(i>=CDC_DATA_OUT_EP_SIZE) break;
			USB_Out_Buffer[i++]=getcUSART();
		}
		putUSBUSART(&USB_Out_Buffer[0],	i);
		NextUSBOut = 0;
	}

	CDCTxService();
}
示例#11
0
void putINT_serial(u16 vcdc) {
    unsigned int temp, dvd = 10000;
    char i = 0, k = 0;
    temp = vcdc;
    for (i = 0; i < 5; i++) {
        temp = vcdc / dvd;
        if (temp) k++;
        if (k) putcUSART((char) temp + '0');
        vcdc = vcdc - (temp * dvd);
        dvd /= 10;
    }
}
示例#12
0
文件: main.c 项目: niamster/uc-pic
static void processCy7c4xxFifo(void)
{
    unsigned char c;
    static unsigned char *cy7c4xx_buf_ptr = InDataPacket;
    static unsigned char len = 0;

    if (cy7c4xxPull(&c) != 0)
        return;

    if (len) {
        *cy7c4xx_buf_ptr = c;
        ++cy7c4xx_buf_ptr;
        --len;

        if (len == 0) {
#if DEBUG
            if (usbfifo_debug_operation.dump_fifo_out == 1) {
                unsigned char l = cy7c4xx_buf_ptr-InDataPacket, i;
                unsigned char b[12];
                putrsUSART("FIFO IN: '");
                for (i=0;i<l;++i) {
                    if (i != 0) {
                        while (BusyUSART());
                        putcUSART(' ');
                    }
                    sprintf(b, "%02x", InDataPacket[i]);
                    putsUSART(b);
                }
                sprintf(b, "' len=%3d\r\n", l);
                putsUSART(b);
            }

            if (usbfifo_debug_operation.fifo_loopback == 1) {
                unsigned char l = cy7c4xx_buf_ptr-InDataPacket, i; /* length of incoming packet _must_ not exceed the length of outgoing */
                fifo9403aPush(l, 1);
                for (i=0;i<l;++i)
                    fifo9403aPush(InDataPacket[i], 1);
            }
#endif

            /* FIXME: use real ping-pong */
            while (USBHandleBusy(UsbInDataHandle)); // should not loop, anyway ...
            UsbInDataHandle = USBGenWrite(USBGEN_DATA_EP_NUM, (BYTE*)&InDataPacket, cy7c4xx_buf_ptr-InDataPacket);
            while (USBHandleBusy(UsbInDataHandle)); // have to wait here as full ping-pong is not implemented
                                                    // and thus we don't want data from FIFO override the data being sent here

            cy7c4xx_buf_ptr = InDataPacket;
        }
    } else {
        len = c;
    }
}
示例#13
0
void sendString(rom char* data, int length)		///Works
{
	int i;
	unsigned char temp;
	Delay10KTCYx(100);
	while(BusyUSART());
	for(i = 0; i < length; i++)
	{
		temp = data[i];
		putcUSART(temp);
		Delay100TCYx(100);
	}	
}
示例#14
0
/*
*------------------------------------------------------------------------------
* void PutrsUART(const rom char *data)
*
* Summary	: Send the rom character string through UART
*
* Input		: const rom char *data - pointer to the null terminated string rom.
*
* Output	: None
*------------------------------------------------------------------------------
*/
void PutrsUART(const rom char *data)
{
	TX_EN = 1;	//enable the tx control for rs485 communication
	Delay10us(1);
  do
  {
	// Wait till the last bit trasmision
    while(BusyUSART());
	// Transmit a byte
    putcUSART(*data++);
  } while( *data != '\0');

	TX_EN = 0;	//disable the tx control for rs485 communication
	Delay10us(1);
}
示例#15
0
void ProcessIO(void)
{	
	uchar cnt;
	//Blink	the	LEDs according to the USB device status
	BlinkUSBStatus();
	// User	Application	USB	tasks
	if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1))	return;

	// only check	for	new	USB	buffer if the old RS232	buffer is
	// empty.	 This will cause additional	USB	packets	to be NAK'd

	// RS232_送信バッファに HostPC から届いたデータをFillする.
	if (LastRS232Out == 0) {						  
		LastRS232Out = getsUSBUSART(RS232_Out_Data,64);	//until	the	buffer is free.
		if(LastRS232Out	> 0) {
			RS232cp	= 0;  // Reset the current position
		}
	}

	for(cnt=0;cnt<32;cnt++) {

		//USARTが送信可であれば RS232_送信バッファの内容を USARTに 1文字送る.
		if(LastRS232Out && mTxRdyUSART())	{
			putcUSART(RS232_Out_Data[RS232cp]);	//1文字送る.
			++RS232cp;
			if (RS232cp	== LastRS232Out) {
				LastRS232Out=0;
				RS232cp=0;
			}
		}

		//USARTがデータを受信済みであれば RS232_受信バッファに溜める.
		if(mDataRdyUSART()) {
			USB_Out_Buffer[NextUSBOut] = getcUSART();
			++NextUSBOut;
			//USB_Out_Buffer[NextUSBOut] = 0;
		}

	}

	//可能なら、RS232_受信バッファの内容をHostPCに送る.
	if((USBUSARTIsTxTrfReady())	&& (NextUSBOut > 0)){
		putUSBUSART(&USB_Out_Buffer[0],	NextUSBOut);
		NextUSBOut = 0;
	}

	CDCTxService();
}
void main (void) {

    // Interrupt configs
    RCONbits.IPEN = 0;      // Deshabilitar prioridades
    INTCONbits.PEIE = 1;    // Habilitar interrupciones de perifericos
    INTCONbits.GIE = 1;     // Habilitar interrupciones globales

    // Inicializa el USART y lo configura a 8N1, 9600 badios
    OpenUSART(
            USART_TX_INT_OFF &          // TX sin interrupciones
            USART_RX_INT_ON &           // RX con interrupciones
            USART_ASYNCH_MODE &         // Modo asincronico
            USART_EIGHT_BIT &           // 8 bits de datos
            USART_CONT_RX &             // Recepci?n continua
            USART_BRGH_HIGH, 129        // 9600 baudios a 20 mhz (calcular con PicBaudRate)
    );

    // Init LCD
    lcd_init();
    lcd_gotoxy(0,2);
    lcd_putrs("   Temp:        ");

    // Safety?
    __delay_ms(39);

    while (1) {

        if (dataFlag != 0) {
            dataFlag = 0;

            // Convierte el float a string
            sprintf(strGrados, "%2.1f,", grados);

            if      (data == 0xFD) putcUSART(0xFD);         // Control
            else if (data == 0xFF) putsUSART(strGrados);    // Env�a info

        }

        Medir_Temperatura();
        __delay_ms(39);
        grados = Leer_DS18B20();

        lcd_gotoxy(10,2);
        printf("%2.1f", grados);
    }
}
示例#17
0
void uartbuf_flush(UINT channel) {

   unsigned char ch;

   if ((channel == SLAVE_TX) || (channel == SLAVE_HPTX)) {

      while (!cbuffer_isempty(&Uart[channel])) {
         cbuffer_read(&Uart[channel], &ch);
#ifdef DEBUG
         printf("(0x%03X) - ", ch);
#else
         while (BusyUSART());
         putcUSART(ch);
#endif
      }
   }
}
示例#18
0
// Master Mode
void master(void){

  while(1){
    WriteUSART(27);
    putrsUSART (ClrScr);
    putrsUSART (Menu1);

    while(!DataRdyUSART());  //wait for data
    key = ReadUSART();      //read data
    putcUSART(key);

    switch (key) {
    case '1':
      {
        WriteUSART(27);
        putrsUSART (ClrScr);
        putrsUSART (Menu1_1);
        while(!DataRdyUSART());  //wait for data
        key = ReadUSART();      //read data
        break;
      }
    case '2':
      {
        trackmode();
        break;
      }
    case '3':
      {
        WriteUSART(27);
        putrsUSART (ClrScr);
        putrsUSART (Menu1_3);
        manmode();
        break;
      }
	case '4':
	  {
		blink();
	  }
    default:
      {
        putrsUSART (BadKey);
        break;
      }
    }
  }
}
示例#19
0
文件: main.c 项目: Athuli7/Microchip
/********************************************************************
 * Function:        void ProcessIO(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is a place holder for other user
 *                  routines. It is a mixture of both USB and
 *                  non-USB tasks.
 *
 * Note:            None
 *******************************************************************/
void ProcessIO(void)
{   
    //Blink the LEDs according to the USB device status
    BlinkUSBStatus();
    // User Application USB tasks
    if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;

	// only check for new USB buffer if the old RS232 buffer is
	// empty.
	// Additional USB packets will be NAK'd
	// until the buffer is free.
	if (RS232_Out_Data_Rdy == 0)
		{
			LastRS232Out = getsUSBUSART(RS232_Out_Data,64);
			
			if(LastRS232Out > 0)
			{
				RS232_Out_Data_Rdy = 1; // signal
										//buffer full
				RS232cp = 0;// Reset the current position
			}
		}
		
	if(RS232_Out_Data_Rdy && mTxRdyUSART())
	{
		putcUSART(RS232_Out_Data[RS232cp]);
		++RS232cp;
		if (RS232cp == LastRS232Out)
			RS232_Out_Data_Rdy = 0;
	}

	if(mDataRdyUSART())
	{
		USB_Out_Buffer[NextUSBOut] = getcUSART();
		++NextUSBOut;
		USB_Out_Buffer[NextUSBOut] = 0;
	}

	if((mUSBUSARTIsTxTrfReady()) && (NextUSBOut > 0))
	{
		putUSBUSART(&USB_Out_Buffer[0], NextUSBOut);
		NextUSBOut = 0;
	}

    CDCTxService();
}		//end ProcessIO
示例#20
0
//Encapsulates the whole testing process
u8 testPart() {
    PartSS = 0;
    diff = 0;
    part_unit = 'm'; //mV by default
    pins[0] = 'X';
    pins[1] = 'X';
    pins[2] = 'X';

    //returns the number of conducting directions between all 3 pins
    //On return tList, nC, diff, and other variables hold the results
    testConduct();

    //gets the ID of the part that is most probable
    PartSS = getPartSS(); 

    //switches depending on the PartSS value, here is where all the part specific functions all called
    part_val = switchPart(PartSS);

#ifdef HAS_SERIAL_PORT
    putrsUSART("\n\n");
    tListPrint_serial();
    putrsUSART("\nPartSS: ");
    putINT_serial(PartSS);
    putcUSART('\n');
    printPart_serial();
#endif

#ifdef HAS_USB_CDC
    if (terminalF) {
        puts_cdc("\n\n");
        tListPrint_cdc();
        puts_cdc("\nPartSS: ");
        putINT_cdc(PartSS);
        putc_cdc('\n');
        printPart_cdc();
    }
#endif

#ifdef HAS_LCD
    printPart_lcd();
#endif

    if (PartSS) return 1;
    return 0;
}
示例#21
0
void printPart_serial() {
    putrsUSART(type_descs[PartSS]);
    if(PartSS == ERROR || PartSS >= NOID) return;

    putINT_serial(part_val);
    putcUSART(part_unit);
    putcUSART('  ');

    putrsUSART("1:");
    putcUSART(pins[0]);
    putcUSART(' ');

    putrsUSART("2:");
    putcUSART(pins[1]);
    putcUSART(' ');

    putrsUSART("3:");
    putcUSART(pins[2]);
    putcUSART(' ');
}
示例#22
0
//TODO:Funcao facilita leitura de inteiros
int getInt(){
	int i=0;
  int iReturn=0;                  //inteiro a ser retornado.
	while(i<TAM_NUM){               // Atende ao buffer de 5 char
			if(PIR1bits.RCIF){				  //Checa se foi registrador foi carregado
				PIR1bits.RCIF = 0;			  //Reinicializa Flag de recebimento
				cbuffer = RCREG;				  //Recebe dado
				if(cbuffer == 0x0D){ 	    //Checa se foi ENTER
					break;					        //para iteracao
				} else {
				sbuffer[i++] = cbuffer;		//Poe na string para ser convertido
				putcUSART(cbuffer);				//imprime
        while(BusyUSART());
				}	}	}
  puts(CRLF);				              //quebra linha
  while(BusyUSART());
  iReturn = atoi(sbuffer);        //Armazena return
  while(i>=0) sbuffer[i--] = '\0';//limpa para uso futuro
  return iReturn;
}
示例#23
0
文件: env.c 项目: simait/TinyTimber
/**
 * \brief The PIC18 print variable function.
 *
 * Used for debugging purposes only.
 */
void pic18_print_var(unsigned long var)
{
	static unsigned char digits[] =
	{
		'0', '1', '2', '3',
		'4', '5', '6', '7',
		'8', '9', 'a', 'b',
		'c', 'd', 'e', 'f'
	};
	unsigned char i, *tmp = (unsigned char*)&var;

	tmp += 3;
	for (i=0;i<4;i++, tmp--)
	{
		while (BusyUSART());
		putcUSART(digits[*tmp >> 4]);
		while (BusyUSART());
		putcUSART(digits[*tmp & 0xf]);
	}
	while (BusyUSART());
}
示例#24
0
void uartLoopbackSM(LoopbackData *data){

  switch(data->state){
    case WAIT_DATA:
      if(DataRdyUSART() == 0)
        break;
      data->dataByte = getcUSART();
      data->state = WAIT_TO_TX;
      break;

    case WAIT_TO_TX:
      if(BusyUSART() == 1)
        break;
      putcUSART(data->dataByte);
      data->state = WAIT_DATA;
      break;
      
    default:
      break;
  }
}
示例#25
0
void main()
{
	unsigned char i2cdata = 0, usartdata = 0;
	unsigned char data = 0;
	unsigned char str[] = "nom de la toune";
	unsigned char AUTO[] = "Auto";
	unsigned char NORMAL[] = "Normal";
	unsigned char CUTOM1[] = "Custom 1";
	unsigned char CUTOM2[] = "Custom 2";
	unsigned char CUTOM3[] = "Custom 3";
	// Config position
	short xposMMODE = 40;
	short yposMMODE = 2; //(tranche de 8)


	initialisation();	//Initialise tout


LED1=0;
LED2=1;
LED3=1;
		while(debut)
		{
			//chech dsp pour signal autocorrélation puis debut à 1
			if (read1==0xFF)
				debut=0;
			LED1 = 0;
		}
		LED1 = 1;	
		//Boucle infinie
	while(1)
	{
		//Affichage de l'écran initial
		if(!debut)
		{
			GLCD_Bitmap(logo, 0, 0, 128, 64);
			Delay10KTCYx(0);
			Delay10KTCYx(0);
			Delay10KTCYx(0);
			Delay10KTCYx(0);
			Delay10KTCYx(0);
			Delay10KTCYx(0);
			Delay10KTCYx(0);
			Delay10KTCYx(0);
			GLCD_ClearScreen();
			GLCD_Bitmap(PAUSE, 47, 2, 35, 24);
			debut=1;
		}

		if(last_nombre != nombre)	//Si une transition a eu lieu, gérer les menus d'affichage
		{
			switch(nombre)
			{
				case 0:
					
					GLCD_Bitmap(ICONES, 0, 6, 128, 16);
					GLCD_Bitmap(MODEselec, 1, 6, 68, 16);
					GLCD_GoTo(5,7);
					if(modeselect == 0)
						GLCD_WriteString(AUTO,1);
					else if(modeselect == 1)
						GLCD_WriteString(NORMAL,1);	
					else if(modeselect == 2)
						GLCD_WriteString(CUTOM1,1);							
					else if(modeselect == 3)
						GLCD_WriteString(CUTOM2,1);
					else if(modeselect == 4)
						GLCD_WriteString(CUTOM3,1);							
					if(proj)
						GLCD_Bitmap(flecheICO, 75, 5, 8, 8); //SPOT
					else
						GLCD_Bitmap(flecheNULL, 75, 5, 8, 8); //SPOT
					if(strob)
						GLCD_Bitmap(flecheICO, 95, 5, 8, 8); //STROB
					else
						GLCD_Bitmap(flecheNULL, 95, 5, 8, 8); //STROB	
					if(vu)
						GLCD_Bitmap(flecheICO, 115, 5, 8, 8); //BARR
					else
						GLCD_Bitmap(flecheNULL, 115, 5, 8, 8); //BARR
					break;
				case 1:
					//GLCD_ClearScreen();
					GLCD_Bitmap(ICONES, 0, 6, 128, 16);
					GLCD_Bitmap(SPOTselec, 70, 6, 18, 16);
					GLCD_GoTo(5,7);
					if(modeselect == 0)
						GLCD_WriteString(AUTO,0);
					else if(modeselect == 1)
						GLCD_WriteString(NORMAL,0);	
					else if(modeselect == 2)
						GLCD_WriteString(CUTOM1,0);							
					else if(modeselect == 3)
						GLCD_WriteString(CUTOM2,0);
					else if(modeselect == 4)
						GLCD_WriteString(CUTOM3,0);							
					if(proj)
						GLCD_Bitmap(flecheICO, 75, 5, 8, 8); //SPOT
					else
						GLCD_Bitmap(flecheNULL, 75, 5, 8, 8); //SPOT
					if(strob)
						GLCD_Bitmap(flecheICO, 95, 5, 8, 8); //STROB
					else
						GLCD_Bitmap(flecheNULL, 95, 5, 8, 8); //STROB	
					if(vu)
						GLCD_Bitmap(flecheICO, 115, 5, 8, 8); //BARR
					else
						GLCD_Bitmap(flecheNULL, 115, 5, 8, 8); //BARR
					break;
				case 2:
					//GLCD_ClearScreen();
					GLCD_Bitmap(ICONES, 0, 6, 128, 16);
					GLCD_Bitmap(STROBselec, 90, 6, 18, 16);
					GLCD_GoTo(5,7);
					if(modeselect == 0)
						GLCD_WriteString(AUTO,0);
					else if(modeselect == 1)
						GLCD_WriteString(NORMAL,0);	
					else if(modeselect == 2)
						GLCD_WriteString(CUTOM1,0);							
					else if(modeselect == 3)
						GLCD_WriteString(CUTOM2,0);
					else if(modeselect == 4)
						GLCD_WriteString(CUTOM3,0);							
					if(proj)
						GLCD_Bitmap(flecheICO, 75, 5, 8, 8); //SPOT
					else
						GLCD_Bitmap(flecheNULL, 75, 5, 8, 8); //SPOT
					if(strob)
						GLCD_Bitmap(flecheICO, 95, 5, 8, 8); //STROB
					else
						GLCD_Bitmap(flecheNULL, 95, 5, 8, 8); //STROB	
					if(vu)
						GLCD_Bitmap(flecheICO, 115, 5, 8, 8); //BARR
					else
						GLCD_Bitmap(flecheNULL, 115, 5, 8, 8); //BARR
					break;
				case 3:
					//GLCD_ClearScreen();
					GLCD_Bitmap(ICONES, 0, 6, 128, 16);
					GLCD_Bitmap(BARRselec, 110, 6, 18, 16);
					GLCD_GoTo(5,7);
					if(modeselect == 0)
						GLCD_WriteString(AUTO,0);
					else if(modeselect == 1)
						GLCD_WriteString(NORMAL,0);	
					else if(modeselect == 2)
						GLCD_WriteString(CUTOM1,0);							
					else if(modeselect == 3)
						GLCD_WriteString(CUTOM2,0);
					else if(modeselect == 4)
						GLCD_WriteString(CUTOM3,0);								
					if(proj)
						GLCD_Bitmap(flecheICO, 75, 5, 8, 8); //SPOT
					else
						GLCD_Bitmap(flecheNULL, 75, 5, 8, 8); //SPOT
					if(strob)
						GLCD_Bitmap(flecheICO, 95, 5, 8, 8); //STROB
					else
						GLCD_Bitmap(flecheNULL, 95, 5, 8, 8); //STROB	
					if(vu)
						GLCD_Bitmap(flecheICO, 115, 5, 8, 8); //BARR
					else
						GLCD_Bitmap(flecheNULL, 115, 5, 8, 8); //BARR
					break;
				case 4:
					GLCD_ClearScreen();
					GLCD_Bitmap(titreMODE, 0, 0, 128, 16);
					GLCD_GoTo(xposMMODE,yposMMODE);
					GLCD_WriteString(AUTO,1);
					GLCD_GoTo(xposMMODE,yposMMODE+1);
					GLCD_WriteString(NORMAL,0);
					GLCD_GoTo(xposMMODE,yposMMODE+2);
					GLCD_WriteString(CUTOM1,0);
					GLCD_GoTo(xposMMODE,yposMMODE+3);
					GLCD_WriteString(CUTOM2,0);
					GLCD_GoTo(xposMMODE,yposMMODE+4);
					GLCD_WriteString(CUTOM3,0);
					break;	
				case 5:
					GLCD_ClearScreen();
					GLCD_Bitmap(titreMODE, 0, 0, 128, 16);
					GLCD_GoTo(xposMMODE,yposMMODE);
					GLCD_WriteString(AUTO,0);
					GLCD_GoTo(xposMMODE,yposMMODE+1);
					GLCD_WriteString(NORMAL,1);
					GLCD_GoTo(xposMMODE,yposMMODE+2);
					GLCD_WriteString(CUTOM1,0);
					GLCD_GoTo(xposMMODE,yposMMODE+3);
					GLCD_WriteString(CUTOM2,0);
					GLCD_GoTo(xposMMODE,yposMMODE+4);
					GLCD_WriteString(CUTOM3,0);
					break;
				case 6:
					GLCD_ClearScreen();
					GLCD_Bitmap(titreMODE, 0, 0, 128, 16);
					GLCD_GoTo(xposMMODE,yposMMODE);
					GLCD_WriteString(AUTO,0);
					GLCD_GoTo(xposMMODE,yposMMODE+1);
					GLCD_WriteString(NORMAL,0);
					GLCD_GoTo(xposMMODE,yposMMODE+2);
					GLCD_WriteString(CUTOM1,1);
					GLCD_GoTo(xposMMODE,yposMMODE+3);
					GLCD_WriteString(CUTOM2,0);
					GLCD_GoTo(xposMMODE,yposMMODE+4);
					GLCD_WriteString(CUTOM3,0);
					break;
				case 7:
					GLCD_ClearScreen();
					GLCD_Bitmap(titreMODE, 0, 0, 128, 16);
					GLCD_GoTo(xposMMODE,yposMMODE);
					GLCD_WriteString(AUTO,0);
					GLCD_GoTo(xposMMODE,yposMMODE+1);
					GLCD_WriteString(NORMAL,0);
					GLCD_GoTo(xposMMODE,yposMMODE+2);
					GLCD_WriteString(CUTOM1,0);
					GLCD_GoTo(xposMMODE,yposMMODE+3);
					GLCD_WriteString(CUTOM2,1);
					GLCD_GoTo(xposMMODE,yposMMODE+4);
					GLCD_WriteString(CUTOM3,0);
					break;
				case 8:
					GLCD_ClearScreen();
					GLCD_Bitmap(titreMODE, 0, 0, 128, 16);
					GLCD_GoTo(xposMMODE,yposMMODE);
					GLCD_WriteString(AUTO,0);
					GLCD_GoTo(xposMMODE,yposMMODE+1);
					GLCD_WriteString(NORMAL,0);
					GLCD_GoTo(xposMMODE,yposMMODE+2);
					GLCD_WriteString(CUTOM1,0);
					GLCD_GoTo(xposMMODE,yposMMODE+3);
					GLCD_WriteString(CUTOM2,0);
					GLCD_GoTo(xposMMODE,yposMMODE+4);
					GLCD_WriteString(CUTOM3,1);
					break;					
			}
			last_nombre = nombre;
			}
			//Si on appuit sur le bouton, activer l'actuateur en question ou changer de menu
			if(!ENC_SW)
			{
				while(!ENC_SW);
				Delay10KTCYx(125);
				switch(nombre)
					{
						case 0:
							emplacement=2;
							nombre=modeselect+4;
							last_nombre=0;
						break;
						case 1:
						if(proj)
							proj=0;
						else
							proj=1;
						last_nombre=0;
						break;
						case 2:
						if(strob)
							strob=0;
						else
							strob=1;
						last_nombre=0;
						break;
						case 3:
						if(vu)
							vu=0;
						else
							vu=1;
						last_nombre=0;
						break;
						case 4:
							modeselect=0;
							emplacement=1;
							nombre=0;
							GLCD_ClearScreen();
						break;
						case 5:
							modeselect=1;
							emplacement=1;
							nombre=0;
							GLCD_ClearScreen();
						break;
						case 6:
							modeselect=2;
							emplacement=1;
							nombre=0;
							GLCD_ClearScreen();
						break;
						case 7:
							modeselect=3;
							emplacement=1;
							nombre=0;
							GLCD_ClearScreen();
						break;
						case 8:
							modeselect=4;
							emplacement=1;
							nombre=0;
							GLCD_ClearScreen();
						break;
					}	
			}
		
		//Si la pédale est appuyée, changer de on-off
		if(!PORTBbits.RB3)
		{
			while(!PORTBbits.RB3);		//Attente que la pédale soit relâché
			if(etatplay==0)
			{
				play=1;
				pause=0;
				etatplay=1;
			}
			else
			{
				pause=1;
				last_nombre=9;
				etatplay=0;
			}
		}
// ---------------------------------------------------------------------------------------
// PLAY
		if(play)
		{
			//Affiche play à l'écran
			GLCD_Bitmap(PLAY, 47, 2, 35, 24);
			
			//Envoie le mode vers le dsp
			euart_out=modeselect;
			while(BusyUSART());
			putcUSART(euart_out);
			Delay10KTCYx(0);
			Delay10KTCYx(0);
			Delay10KTCYx(0);
			GLCD_ClearScreen();
			last_nombre=9;	
			play=1;
		}
// ---------------------------------------------------------------------------------------
// PAUSE
		if(emplacement == 1)
		{
			//Si non-pause, afficher les barres graphiques
			if(pause==0)
			{
				graphVU(chan_L,chan_R);
			}
			//Si pause, afficher l'image du pause
			else if(pause==1 && last_nombre!=nombre)
			{
				GLCD_ClearScreen();			
				GLCD_Bitmap(PAUSE, 47, 2, 35, 24);
				last_nombre=9;
			}
			//Affiche le nom de la chanson en cours
			GLCD_GoTo(2,0);
			if(toune==1)
				GLCD_WriteString(music_1,0);						
			else if(toune==2)
				GLCD_WriteString(music_2,0);
			else if(toune==3)
				GLCD_WriteString(music_3,0);			
		}

// I2C,  actualiser la FFT et envoyer les données vers le contrôleur principal
		if(flag_i2c)
		{
			flag_i2c=0;
			//Si trame FFT initiale détecté, commence à mettre à jour la FFT
			if((read3&0b00010000)==0x10)
			{
				compteur_fft=1; 
			}
			//Met à jour chaque trame de la FFT
			switch(compteur_fft)
					{
						case 1:
							fft1=(read3&0b00001111);
						break;
						case 2:
							fft2=(read3&0b00001111);
						break;
						case 3:
							fft3=(read3&0b00001111);
						break;
						case 4:
							fft4=(read3&0b00001111);
						break;
						case 5:
							fft5=(read3&0b00001111);
						break;
						case 6:
							fft6=(read3&0b00001111);
						break;
						case 7:
							fft7=(read3&0b00001111);
						break;
						case 8:
							fft8=(read3&0b00001111);
						break;
						case 9:
							fft9=(read3&0b00001111);
						break;
						case 10:
							fft10=(read3&0b00001111);
						break;
						case 11:
							fft11=(read3&0b00001111);
						break;
						case 12:
							fft12=(read3&0b00001111);
						break;
						case 13:
							fft13=(read3&0b00001111);
						break;
						case 14:
							fft14=(read3&0b00001111);
						break;
						case 15:
							fft15=(read3&0b00001111);
						break;
						case 16:
							fft16=(read3&0b00001111);
							compteur_fft=0;
						break;
						default:
							LED2=1;
						break;
					}	
			//Lorsque la FFT est actualiser, la faire afficher à l'écran
			if(compteur_fft==1 && (emplacement ==1)  && (etatplay==1))
				graphFFT(2*fft1,2*fft2,2*fft3,2*fft4,2*fft5,2*fft6,2*fft7,2*fft8,2*fft9,2*fft10,2*fft11,2*fft12,2*fft13,2*fft14,2*fft15,2*fft16);	
			compteur_fft++;
			//Choix de la chanson selon les données reçu
			if((read4&0b00001111)==0b00000001)
				toune=1;
			else if((read4&0b00001111)==0b00000010)
				toune=2;
			else if((read4&0b00001111)==0b00000011)
				toune=3;
			//Masques pour savoir les actuateurs à activer
			i2c_actuateur=0b00001000;
			if(vu && !pause)
				i2c_actuateur |= 0b00000001;			
			if(proj && !pause)
				i2c_actuateur |= 0b00000010;
			if(strob && !pause)
				i2c_actuateur |= 0b00000100;
			
			//Émet I2C uniquement sur nouvelles données
			if((last_i2c_1 != read2) || (last_i2c_2 != i2c_actuateur))
			{
				tst_str[1] = read2;
				tst_str[2] = i2c_actuateur;
				send_str_I2C(0x40, tst_str);
			}
			last_i2c_1 = read2;		
			last_i2c_2 = i2c_actuateur;	
		}
		if(play)
		{
			while(BusyUSART());
			putcUSART(euart_out);
			play=0;
		}
	}
} 
示例#26
0
文件: main.c 项目: iruka-/ORANGEpico
/********************************************************************
 * Function:        void ProcessIO(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is a place holder for other user
 *                  routines. It is a mixture of both USB and
 *                  non-USB tasks.
 *
 * Note:            None
 *******************************************************************/
void ProcessIO(void)
{   
    //Blink the LEDs according to the USB device status
    BlinkUSBStatus();
    // User Application USB tasks
    if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;

	if (RS232_Out_Data_Rdy == 0)  // only check for new USB buffer if the old RS232 buffer is
	{						  // empty.  This will cause additional USB packets to be NAK'd
		LastRS232Out = getsUSBUSART(RS232_Out_Data,64); //until the buffer is free.
		if(LastRS232Out > 0)
		{	
			RS232_Out_Data_Rdy = 1;  // signal buffer full
			RS232cp = 0;  // Reset the current position
		}
	}

    //Check if one or more bytes are waiting in the physical UART transmit
    //queue.  If so, send it out the UART TX pin.
	if(RS232_Out_Data_Rdy && mTxRdyUSART())
	{
    	#if defined(USB_CDC_SUPPORT_HARDWARE_FLOW_CONTROL)
        	//Make sure the receiving UART device is ready to receive data before 
        	//actually sending it.
        	if(UART_CTS == USB_CDC_CTS_ACTIVE_LEVEL)
        	{
        		putcUSART(RS232_Out_Data[RS232cp]);
        		++RS232cp;
        		if (RS232cp == LastRS232Out)
        			RS232_Out_Data_Rdy = 0;
    	    }
	    #else
	        //Hardware flow control not being used.  Just send the data.
    		putcUSART(RS232_Out_Data[RS232cp]);
    		++RS232cp;
    		if (RS232cp == LastRS232Out)
    			RS232_Out_Data_Rdy = 0;	    
	    #endif
	}

    //Check if we received a character over the physical UART, and we need
    //to buffer it up for eventual transmission to the USB host.
	if(mDataRdyUSART() && (NextUSBOut < (CDC_DATA_OUT_EP_SIZE - 1)))
	{
		USB_Out_Buffer[NextUSBOut] = getcUSART();
		++NextUSBOut;
		USB_Out_Buffer[NextUSBOut] = 0;
	}
	
	#if defined(USB_CDC_SUPPORT_HARDWARE_FLOW_CONTROL)
    	//Drive RTS pin, to let UART device attached know if it is allowed to 
    	//send more data or not.  If the receive buffer is almost full, we 
    	//deassert RTS.
    	if(NextUSBOut <= (CDC_DATA_OUT_EP_SIZE - 5u))
    	{
            UART_RTS = USB_CDC_RTS_ACTIVE_LEVEL;
        }   	
        else
        {
        	UART_RTS = (USB_CDC_RTS_ACTIVE_LEVEL ^ 1);
        }    
    #endif	

    //Check if any bytes are waiting in the queue to send to the USB host.
    //If any bytes are waiting, and the endpoint is available, prepare to
    //send the USB packet to the host.
	if((USBUSARTIsTxTrfReady()) && (NextUSBOut > 0))
	{
		putUSBUSART(&USB_Out_Buffer[0], NextUSBOut);
		NextUSBOut = 0;
	}

    CDCTxService();

}//end ProcessIO
示例#27
0
void main()
{
    int i;

    TRISAbits.TRISA0 = 1;   //Direciona o pino 0 da porta A como entrada
    TRISAbits.TRISA3 = 1;   //Direciona o pino 3 da porta A como entrada
    TRISCbits.TRISC2 = 0;	//Direciona o pino 2 da porta C como saída (Aquecimento)
    TRISAbits.TRISA4 = 1;   //Direciona o pino 4 da porta A como entrada (B2)

    OpenUSART(USART_TX_INT_OFF		//desabilita interrupção de transmissão
              & USART_RX_INT_OFF	//desabilita interrupção de recepção
              & USART_ASYNCH_MODE	//modo assíncrono
              & USART_EIGHT_BIT		//transmissão e recepção em 8 bits
              & USART_BRGH_HIGH,	//Baud Rate em alta velocidade
              25);					//SPBRG p/ 19200 bps

    ADCON2 = 0b10100001;     /*ADFM1 = 1 -> Resultado da conversão AD
                                    ... justificado à direita
                                    -
                                    ****Velocidade de aquisição em 8TAD
                                    ACQT2 = 1
                                    ACQT1 = 0
                                    ACQT0 = 0
                                    ****Fonte de clock em Fosc/8
                                    ADCS2 = 0
                                    ADCS1 = 0
                                    ADCS0 = 1*/


    ADCON1 = 0b00001011;      /* -
                           	 -
                             VCFG1 = 0 -> Vref- = terra
                             VCFG0 = 1 -> Vref+ = VDD
                             *****Seleciona os canais AN0 e AN3 como analógicos
                             PCFG3 = 1
                             PCFG2 = 1
                             PCFG1 = 0
                             PCFG0 = 1*/

    msg_inicial();


    while(1)
    {
        while(!DataRdyUSART());  //Aguarda a chegada de um caractere no buffer de recepção

        rec[i] = getcUSART();	    //recebe o caractere e armazena no índice n_dado da
        //matriz n_dado

        putcUSART(rec[i]);
        Delay10KTCYx(1);   	//Gera um delay de 5ms
        i++;

        if(rec[i-1]==0x0D)
        {
            trata_serial();
            i=0;
            msg_inicial();
        }



    }
}
示例#28
0
void tListPrint_serial() {
    u8 i, t1;
    u16 t2;

    putrsUSART("\nVcc:");
    putINT_serial(VCC);

    putrsUSART("\nnC:");
    putcUSART(nC + '0');

    putrsUSART("\ndiff:");
    putcUSART(diff + '0');
    
    for (i = 0; i < 12; i++) {
        putrsUSART("\nCP");
        putcUSART(i + '1');
        putrsUSART(": ");

        t1 = (u8) tList[i][0];
        putcUSART(t1 + '0');

        putrsUSART("->");

        t1 = (u8) tList[i][1];
        putcUSART(t1 + '0');

        putrsUSART(" Value: ");
        t2 = tList[i][2];
        putINT_serial(t2);
    }

    for (i = 0; i < 3; i++) {
        putrsUSART("\ntIN");
        putcUSART(i + '1');
        putrsUSART(": ");
        putcUSART(tIN[i] + '0');
    }

    for (i = 0; i < 3; i++) {
        putrsUSART("\ntOUT");
        putcUSART(i + '1');
        putrsUSART(": ");
        putcUSART(tOUT[i] + '0');
    }

    for (i = 0; i < 3; i++) {
        putrsUSART("\ntC");
        putcUSART(i + '1');
        putrsUSART(": ");
        putcUSART(tC[i] + '0');
    }

    for (i = 0; i < 8; i++) {
        putrsUSART("\ntN");
        putcUSART(i + '1');
        putrsUSART(": ");
        putcUSART(tN[i] + '0');
    }
}
示例#29
0
文件: main.c 项目: niamster/uc-pic
static void processUsbCommands(void)
{
#if defined(USB_POLLING)
    // Check bus status and service USB interrupts.
    USBDeviceTasks(); // Interrupt or polling method.  If using polling, must call
    // this function periodically.  This function will take care
    // of processing and responding to SETUP transactions
    // (such as during the enumeration process when you first
    // plug in).  USB hosts require that USB devices should accept
    // and process SETUP packets in a timely fashion.  Therefore,
    // when using polling, this function should be called
    // regularly (such as once every 1.8ms or faster** [see
    // inline code comments in usb_device.c for explanation when
    // "or faster" applies])  In most cases, the USBDeviceTasks()
    // function does not take very long to execute (ex: <100
    // instruction cycles) before it returns.
#endif

    // Note: The user application should not begin attempting to read/write over the USB
    // until after the device has been fully enumerated.  After the device is fully
    // enumerated, the USBDeviceState will be set to "CONFIGURED_STATE".
    if ((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1))
        return;

    // As the device completes the enumeration process, the UsbCbInitEP() function will
    // get called.  In this function, we initialize the user application endpoints (in this
    // example code, the user application makes use of endpoint 1 IN and endpoint 1 OUT).
    // The USBGenRead() function call in the UsbCbInitEP() function initializes endpoint 1 OUT
    // and "arms" it so that it can receive a packet of data from the host.  Once the endpoint
    // has been armed, the host can then send data to it (assuming some kind of application software
    // is running on the host, and the application software tries to send data to the USB device).

    // If the host sends a packet of data to the endpoint 1 OUT buffer, the hardware of the SIE will
    // automatically receive it and store the data at the memory location pointed to when we called
    // USBGenRead().  Additionally, the endpoint handle (in this case UsbOutCmdHandle) will indicate
    // that the endpoint is no longer busy.  At this point, it is safe for this firmware to begin reading
    // from the endpoint buffer, and processing the data.  In this example, we have implemented a few very
    // simple commands.  For example, if the host sends a packet of data to the endpoint 1 OUT buffer, with the
    // first byte = 0x80, this is being used as a command to indicate that the firmware should "Toggle LED(s)".
    if (!USBHandleBusy(UsbOutCmdHandle)) { // Check if the endpoint has received any data from the host.
#if DEBUG
        unsigned char l = USBHandleGetLength(UsbOutCmdHandle);

        if (usbfifo_debug_operation.dump_usb_out == 1) {
            unsigned char b[16];
            unsigned char i;
            putrsUSART("USB OUT: '");
            for (i=0;i<l;++i) {
                if (i != 0) {
                    while (BusyUSART());
                    putcUSART(' ');
                }
                sprintf(b, "%02x", OutCmdPacket[i]);
                putsUSART(b);
            }
            sprintf(b, "' len=%3d\r\n", l);
            putsUSART(b);
        }

        if (usbfifo_debug_operation.usb_loopback == 1) {
            unsigned char i;
            // Now check to make sure no previous attempts to send data to the host are still pending.  If any attemps are still
            // pending, we do not want to write to the endpoint 1 IN buffer again, until the previous transaction is complete.
            // Otherwise the unsent data waiting in the buffer will get overwritten and will result in unexpected behavior.
            while (USBHandleBusy(UsbInCmdHandle));

            for (i=0;i<l;++i)
                InCmdPacket[i] = OutCmdPacket[i];

            // The endpoint was not "busy", therefore it is safe to write to the buffer and arm the endpoint.
            // The USBGenWrite() function call "arms" the endpoint (and makes the handle indicate the endpoint is busy).
            // Once armed, the data will be automatically sent to the host (in hardware by the SIE) the next time the
            // host polls the endpoint.  Once the data is successfully sent, the handle (in this case UsbInCmdHandle)
            // will indicate the the endpoint is no longer busy.
            UsbInCmdHandle = USBGenWrite(USBGEN_CMD_EP_NUM, (BYTE*)&InCmdPacket, l);
        }
#endif

        switch (OutCmdPacket[0]) {
#if DEBUG
            case USBFIFO_CMD_DUMP_USB_OUT:
                usbfifo_debug_operation.dump_usb_out ^= 1;
                break;
            case USBFIFO_CMD_DUMP_FIFO_OUT:
                usbfifo_debug_operation.dump_fifo_out ^= 1;
                break;
            case USBFIFO_CMD_FIFO_LOOPBACK:
                usbfifo_debug_operation.fifo_loopback ^= 1;
                break;
            case USBFIFO_CMD_USB_LOOPBACK:
                usbfifo_debug_operation.usb_loopback ^= 1;
                break;
#endif
            default:
                {
                    unsigned char b[8];
                    putrsUSART("Unexpected cmd=");
                    sprintf(b, "0x%2X\r\n", OutCmdPacket[0]);
                    putsUSART(b);
                }
                break;
        }

        // Re-arm the OUT endpoint for the next packet:
        // The USBGenRead() function call "arms" the endpoint (and makes it "busy").  If the endpoint is armed, the SIE will
        // automatically accept data from the host, if the host tries to send a packet of data to the endpoint.  Once a data
        // packet addressed to this endpoint is received from the host, the endpoint will no longer be busy, and the application
        // can read the data which will be sitting in the buffer.
        UsbOutCmdHandle = USBGenRead(USBGEN_CMD_EP_NUM, (BYTE*)&OutCmdPacket, USBGEN_EP_SIZE);
    }

    if (!USBHandleBusy(UsbOutDataHandle)) {
#if USBGEN_EP_SIZE > FIFO_9403A_MAX_MSG_LEN
#error "Transfer of more than FIFO_9403A_MAX_MSG_LEN not implemented"
#endif
        unsigned char l = USBHandleGetLength(UsbOutDataHandle);
        unsigned char i;

#if DEBUG
        if (usbfifo_debug_operation.dump_usb_out == 1) {
            unsigned char b[16];
            putrsUSART("USB OUT: '");
            for (i=0;i<l;++i) {
                if (i != 0) {
                    while (BusyUSART());
                    putcUSART(' ');
                }
                sprintf(b, "%02x", OutDataPacket[i]);
            }
            sprintf(b, "' len=%3d\r\n", l);
            putsUSART(b);
        }

        if (usbfifo_debug_operation.usb_loopback == 1) {
            while (USBHandleBusy(UsbInDataHandle)); // ensure that FIFO data left the device

            for (i=0;i<l;++i)
                InDataPacket[i] = OutDataPacket[i];

            /* FIXME: use real ping-pong */
            UsbInDataHandle = USBGenWrite(USBGEN_DATA_EP_NUM, (BYTE*)&InDataPacket, l);
            while (USBHandleBusy(UsbInDataHandle)); // have to wait here as full ping-pong is not implemented
                                                    // and thus we don't want data from FIFO override the data being sent here
        }
#endif

        fifo9403aPush(l, 1);
        for (i=0;i<l;++i)
            fifo9403aPush(OutDataPacket[i], 1);

        UsbOutDataHandle = USBGenRead(USBGEN_DATA_EP_NUM, (BYTE*)&OutDataPacket, USBGEN_EP_SIZE);
    }
}