Esempio n. 1
0
void main(void) {

    TRISA = 0x0;
    TRISB = 0x0;
    TRISC = 0x0;
    PORTA = 0x0;
    PORTB = 0x0;
    PORTC = 0x0;
    LATA = 0x0;
    LATB = 0x0;
    LATC = 0x0;

    signed char length;
    unsigned char msgtype;
    uart_comm uc;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    uart_thread_struct uthread_data; // info for uart_lthread
    timer0_thread_struct t0thread_data;
    timer1_thread_struct t1thread_data; // info for timer1_lthread
    encoder_struct encoder_data;
    sensor_data sensors;

#ifdef __USE18F2680
    OSCCON = 0xFC; // see datasheet
    // We have enough room below the Max Freq to enable the PLL for this chip
    OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line
#else
    OSCCON = 0x82; // see datasheeet
    OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on
#endif

#ifdef SENSORPIC
    i2c2_comm ic2;
    init_i2c2(&ic2);
#endif

    // initialize everything
    init_uart_comm(&uc);
    init_i2c(&ic);
    init_encoder(&encoder_data);
    init_timer0_lthread(&t0thread_data);
    init_timer1_lthread(&t1thread_data);
    init_uart_lthread(&uthread_data);
    init_queues();

#ifdef MASTERPIC

    // Enable and set I2C interrupt to high
    i2c_configure_master();
    IPR1bits.SSPIP = 1;
    PIE1bits.SSPIE = 1;

    // initialize Timer0 to go off approximately every 10 ms
    //OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_1);
    CloseTimer0();
    INTCONbits.TMR0IE 	= 0;	//Enable Timer0 Interrupt

    // Configure UART
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_LOW, 9); // 19.2kHz (197910/t - 1 = target)
    IPR1bits.RCIP = 0;
    IPR1bits.TXIP = 0;
    uc.expected = 1;

    PORTB   = 0x0;
    LATB    = 0x0;
    TRISB   = 0x0;
#endif //MASTERPIC

#ifdef SENSORPIC

    // Enable and set I2C interrupt to high
    i2c_configure_slave(SENSORPICADDR);
    IPR1bits.SSPIP = 1;
    PIE1bits.SSPIE = 1;

    i2c2_configure_master();
    IPR3bits.SSP2IP = 1;
    PIE3bits.SSP2IE = 1;

    // Open ADC on channel 1
    ADCON0= 0x01;
    ADCON1=0x30;
    ADCON2=0xa1;
    TRISA=0x0F;
    PIE1bits.ADIE = 1; //Enabling ADC interrupts
    IPR1bits.ADIP = 0; //Setting A/D priority

    // initialize Timer0 to go off approximately every 10 ms
    OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_128);
    INTCONbits.TMR0IE 	= 1;	//Enable Timer0 Interrupt
    INTCON2bits.TMR0IP	= 0;	//TMR0 set to Low Priority Interrupt
#endif //SENSORPIC

#ifdef MOTORPIC
    i2c_configure_slave(MOTORPICADDR);
    // Enable and set I2C interrupt to high
    IPR1bits.SSPIP = 1;
    PIE1bits.SSPIE = 1;

    // Configure UART
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_LOW, 0x9);
    IPR1bits.RCIP = 0;
    IPR1bits.TXIP = 0;

    INTCONbits.TMR0IE = 0;	// Disable Timer0 Interrupt
    
    PORTB   = 0x0;
    LATB    = 0x0;
    TRISB   = 0x0;

    // Set up RB5 as interrupt
    TRISBbits.RB5 = 1;
    INTCON2bits.RBIP = 0;
#endif //MOTORPIC

#ifdef MASTERPIC
    //init_communication(MOTORPICADDR);
    //init_communication(SENSORPICADDR);
#endif

    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();

    while (1) {

        // Spins until a message appears
        block_on_To_msgqueues();

        // Continuously check high priority messages until it is empty
        while((length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer)) >= 0) {
            switch (msgtype) {
                case MSGT_I2C_RQST: {
#ifdef SENSORPIC
                    char command = msgbuffer[0];

                    char length = 0;
                    char buffer[8];

                    switch(command) {
                        case SHORT_IR1_REQ: {
                            length = 2;
                            buffer[0] = command;
                            buffer[1] = 0x11;
                        }   break;
                        case SHORT_IR2_REQ: {
                            length = 2;
                            buffer[0] = command;
                            buffer[1] = 0x22;
                        }   break;
                        case MID_IR1_REQ: {
                            length = 2;
                            buffer[0] = command;
                            buffer[1] = 0x33;
                        }   break;
                        case MID_IR2_REQ: {
                            length = 2;
                            buffer[0] = command;
                            buffer[1] = 0x44;
                        }   break;
                        case COMPASS_REQ: {
                            length = 2;
                            buffer[0] = command;
                            buffer[1] = 0x55;
                        }   break;
                        case ULTRASONIC_REQ: {
                            length = 2;
                            buffer[0] = command;
                            buffer[1] = 0x66;
                        }   break;
                        default: {
                            length = 2;
                            buffer[0] = 0x0;
                            buffer[1] = 0x0;
                        }   break;
                    }
                    if(length > 0) {
                        start_i2c_slave_reply(length,buffer);
                    }
#endif
#ifdef MOTORPIC
                    unsigned char buffer[8];
                    unsigned char length = 0;
                    
                    char command = msgbuffer[0];
                    buffer[0] = command;

                    switch(command) {
                        case MOVE_FORWARD_CMD: {
                            length = 1;
                            motor_move_forward(10);
                            INTCONbits.RBIE = 1; // Temporary
                        }   break;
                        case MOVE_BACKWARD_CMD: {
                            length = 1;
                            motor_move_backward(10);
                        }   break;
                        case TURN_RIGHT_CMD: {
                            length = 1;
                            motor_turn_right(10);
                        }   break;
                        case TURN_LEFT_CMD: {
                            length = 1;
                            motor_turn_left(10);
                        }   break;
                        case STOP_CMD: {
                            length = 1;
                            motor_stop();
                        }   break;
                        case DISTANCE_REQ: {
                            INTCONbits.RBIE = 0; // Temporary
                            buffer[1] = encoder_to_distance();
                            length = 2;
                        }   break;
                        default: {
                            buffer[0] = 0x0;
                            length = 1;
                        }   break;
                    }
                    if(length > 0) {
                        start_i2c_slave_reply(length,buffer);
                    }
#endif
                }   break;
                case MSGT_I2C_DATA: {
                }   break;
                case MSGT_I2C_MASTER_SEND_COMPLETE: {
#ifdef MASTERPIC
/*                    char command = msgbuffer[0];
                    switch(command) {
                        case MOVE_FORWARD_CMD:
                        case MOVE_BACKWARD_CMD:
                        case TURN_RIGHT_CMD:
                        case TURN_LEFT_CMD:
                        case STOP_CMD: {
                            i2c_master_recv(1,MOTORPICADDR);
                        }   break;
                        case DISTANCE_REQ: {
                            i2c_master_recv(2,MOTORPICADDR);
                        }   break;
                        case SHORT_IR1_REQ:
                        case SHORT_IR2_REQ:
                        case MID_IR1_REQ:
                        case MID_IR2_REQ:
                        case COMPASS_REQ:
                        case ULTRASONIC_REQ: {
                            i2c_master_recv(2,SENSORPICADDR);
                        }   break;
                        default: {
                        }   break;
                    }*/
#endif
#ifdef SENSORPIC
                    // Start receiving data from sensor
                    if(t0thread_data.currentState == readCompassState) {
                        i2c2_master_recv(6,COMPASSADDR);
                    }
                    else if(t0thread_data.currentState == readUltrasonicState) {
                        i2c2_master_recv(2,ULTRASONICADDR);
                    }
#endif
                }   break;
                case MSGT_I2C_MASTER_SEND_FAILED: {
                }   break;
                case MSGT_I2C_MASTER_RECV_COMPLETE: {
#ifdef MASTERPIC
                    char buffer[2];
                    char length = 0;
                    
                    char command = msgbuffer[0];                    
                    switch(command) {
                        case MOVE_FORWARD_CMD:
                        case MOVE_BACKWARD_CMD:
                        case TURN_RIGHT_CMD:
                        case TURN_LEFT_CMD:
                        case STOP_CMD: {
                            buffer[0] = command;
                            length = 1;
                        }   break;
                        case DISTANCE_REQ: {
                            buffer[0] = command;
                            buffer[1] = msgbuffer[1];
                            length = 2;
                        }   break;
                        case SHORT_IR1_REQ:
                        case SHORT_IR2_REQ:
                        case MID_IR1_REQ:
                        case MID_IR2_REQ:
                        case COMPASS_REQ:
                        case ULTRASONIC_REQ: {
                            buffer[0] = command;
                            buffer[1] = msgbuffer[1];
                            length = 2;
                        }   break;
                        default: {
                            length = 0;
                        }   break;
                    }
                    if(length > 0) {
                        start_uart_send(length,buffer);
                    }
#endif
#ifdef SENSORPIC
                    // Received data from sensor
                    if(t0thread_data.currentState == readCompassState) {
                        sensors.compassData[0] = msgbuffer[0];
                        sensors.compassData[1] = msgbuffer[1];
                        sensors.compassData[2] = msgbuffer[2];
                        sensors.compassData[3] = msgbuffer[3];
                        sensors.compassData[4] = msgbuffer[4];
                        sensors.compassData[5] = msgbuffer[5];
                    }
                    else if(t0thread_data.currentState == readUltrasonicState) {
                        
                    }
#endif
                }   break;
                case MSGT_I2C_MASTER_RECV_FAILED: {
                }   break;
                case MSGT_I2C_DBG: {
                }   break;
                default: {
                }   break;
            }
        }

        // Error check
        if (length != MSGQUEUE_EMPTY) {
            // Handle Error
        }

        // Check the low priority queue
        if ((length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer)) >= 0) {
            switch (msgtype) {
                case MSGT_TIMER0: {
                    timer0_lthread(&t0thread_data, msgtype, length, msgbuffer);
                }   break;
                case MSGT_TIMER1:
                    timer1_lthread(&t1thread_data, msgtype, length, msgbuffer);
                    break;
                case ADCSC1_ADCH:
                    ADC_lthread(&ADCthread_data, msgtype, length, msgbuffer,&t0thread_data);
                    break;
                case MSGT_OVERRUN:
                case MSGT_UART_DATA: {
                    uart_lthread(&uthread_data, msgtype, length, msgbuffer);
                }   break;
                case MSGT_UART_SEND_COMPLETE: {
                }   break;
                default:
                    break;
            }
        }

        // Error check
        else if (length != MSGQUEUE_EMPTY) {
            // Handle error
        }
    }
}
Esempio n. 2
0
File: main.c Progetto: ahc24/code
void main(void) {
    char c;
    signed char length;
    unsigned char msgtype;
    unsigned char last_reg_recvd;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    unsigned char i;
    uart_thread_struct uthread_data; // info for uart_lthread
    timer1_thread_struct t1thread_data; // info for timer1_lthread
    timer0_thread_struct t0thread_data; // info for timer0_lthread

    t1thread_data.new_move_msg=0;

    #ifdef __USE18F2680
    OSCCON = 0xFC; // see datasheet
    // We have enough room below the Max Freq to enable the PLL for this chip
    OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line
    #else
    #ifdef __USE18F45J10
    OSCCON = 0x82; // see datasheeet
    OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on
    #else
    #ifdef __USE18F26J50
    OSCCON = 0xE0; // see datasheeet
    OSCTUNEbits.PLLEN = 1;
    #else
    #ifdef __USE18F46J50
    OSCCON = 0xE0; //see datasheet
    //Alex:
    //OSCCON : OSCILLATOR CONTROL REGISTER
    //OSCCON[7] : IDLEN = ( 1 = Device enters Idle mode on SLEEP instruction ) or ( 0 = Device enters Sleep mode on SLEEP instruction )
    //OSCCON[6:4] : IRCF; 111 = 8 MHz, 110 = 4 MHz(2), 101 = 2 MHz, 100 = 1 MHz, 011 = 500 kHz, 010 = 250 kHz, 001 = 125 kHz, 000 = 31 kHz
    //OSCCON[3] : OSTS = Oscillator Start-up Time-out Status bit = ( 1 = Oscillator Start-up Timer time-out has expired; primary oscillator is running ) or ( 0 = Oscillator Start-up Timer time-out is running; primary oscillator is not ready )
    //OSCCON[2] : ( Unimplemented: Read as ?1? ) ??????
    //OSCCON[0:1] : SCS = System Clock Select bits
    OSCTUNEbits.PLLEN = 1;
    #else
    Something is messed up.
    The PIC selected is not supported or the preprocessor directives are wrong.
    #endif
    #endif
    #endif
    #endif

    // initialize my uart recv handling code
    //init_uart_recv(&uc);

    // initialize the i2c code
    //Alex:
    //Essentially just sets error and status flags to intial values ( ic is a struct )
    init_i2c(&ic);

    // init the timer1 lthread
    init_timer1_lthread(&t1thread_data);

    // initialize message queues before enabling any interrupts
    init_queues();

    #ifndef __USE18F26J50
    // set direction for PORTB to output
    TRISB = 0x0;
    LATB = 0x0;
    #endif

    // how to set up PORTA for input (for the V4 board with the PIC2680)
    /*
            PORTA = 0x0;	// clear the port
            LATA = 0x0;		// clear the output latch
            ADCON1 = 0x0F;	// turn off the A2D function on these pins
            // Only for 40-pin version of this chip CMCON = 0x07;	// turn the comparator off
            TRISA = 0x0F;	// set RA3-RA0 to inputs
     */

    // initialize Timers
    OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_128);

    
    #ifdef __USE18F26J50
    // MTJ added second argument for OpenTimer1()
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);
    #else
    #ifdef __USE18F46J50
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);

    //configure Timer 3
    /*
    TRISAbits.TRISA5 = 1;
    T3CON = 0x00;
    T3CONbits.TMR3CS = 0x2;
    T3CONbits.T3CKPS = 0x0;
    T3CONbits.RD16 = 0;
    T3CONbits.T3SYNC = 0;
    T3CONbits.TMR3ON = 1;
    RPINR6 = 0x02;
    */

    #else
    OpenTimer1(TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
    #endif
    #endif

    // Decide on the priority of the enabled peripheral interrupts
    // 0 is low, 1 is high
    // Timer1 interrupt
    IPR1bits.TMR1IP = 0;
    // Timer3 interrupt
    IPR2bits.TMR3IP = 0;
    // USART RX interrupt
    IPR1bits.RCIP = 0;
    
    // I2C interrupt
    IPR1bits.SSPIP = 1;     

    // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D)
    #if 1
    // Note that the temperature sensor Address bits (A0, A1, A2) are also the
    // least significant bits of LATB -- take care when changing them
    // They *are* changed in the timer interrupt handlers if those timers are
    //   enabled.  They are just there to make the lights blink and can be
    //   disabled.
    //i2c_configure_slave(0x9E);
    i2c_configure_master(I2C_DEFAULT_PIC_ADDRESS);
    #else
    // If I want to test the temperature sensor from the ARM, I just make
    // sure this PIC does not have the same address and configure the
    // temperature sensor address bits and then just stay in an infinite loop
    i2c_configure_slave(0x9A);
  
    for (;;);
    #endif

    // must specifically enable the I2C interrupts
    PIE1bits.SSPIE = 1;

    
    
    

    /*
    // configure the hardware USART device
    #ifdef __USE18F26J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
    #else
    #ifdef __USE18F46J50

    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);

    #else
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
    #endif
    #endif
    */

    // Alex: Set registers for debug output
    #ifdef DEBUG_MODE
    debug_configure();
    blip();
    blip1();
    blip2();
    blip3();
    blip4();
    #endif

    //uart_send_byte( 0x50 );
    //uart_send_byte( 0x54 );
    
    

    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();

    /* Junk to force an I2C interrupt in the simulator (if you wanted to)
    PIR1bits.SSPIF = 1;
    _asm
    goto 0x08
    _endasm;
     */    

    //Alex: Configure UART for transmit and recieve
    uart_configure();

    // Initialize snesor data buffer
    unsigned char sensor_data[MSGLEN];
    sensor_data[0] = MSGID_SENSOR_RESPONSE;
    for(i=1;i<MSGLEN;i++)
    {
        sensor_data[i] = 0x00;
    }

    // Initialize motor data buffer
    unsigned char motor_data[MSGLEN];
    motor_data[0] = MSGID_MOTOR_RESPONSE;
    for(i=1;i<MSGLEN;i++)
    {
        motor_data[i] = 0x00;
    }

    

    // printf() is available, but is not advisable.  It goes to the UART pin
    // on the PIC and then you must hook something up to that to view it.
    // It is also slow and is blocking, so it will perturb your code's operation
    // Here is how it looks: printf("Hello\r\n");


    // loop forever
    // This loop is responsible for "handing off" messages to the subroutines
    // that should get them.  Although the subroutines are not threads, but
    // they can be equated with the tasks in your task diagram if you
    // structure them properly.
    while (1) {
        // Call a routine that blocks until either on the incoming
        // messages queues has a message (this may put the processor into
        // an idle mode)
        block_on_To_msgqueues();


        // At this point, one or both of the queues has a message.  It
        // makes sense to check the high-priority messages first -- in fact,
        // you may only want to check the low-priority messages when there
        // is not a high priority message.  That is a design decision and
        // I haven't done it here.
        length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } 
        else
        {
            switch (msgtype) {
                case MSGT_TIMER0:
                {
                    timer0_lthread(&t0thread_data, msgtype, length, msgbuffer);
                    break;
                };
                case MSGT_I2C_DATA:
                {

                    switch(msgbuffer[0])
                    {
                        case MSGID_SENSOR_RESPONSE:
                        {
                            for(i=2;i<MSGLEN-2;i++)
                            {
                                sensor_data[i] = msgbuffer[i];
                            }

                            send_uart_message( sensor_data );
                            
                            break;
                        }
                        case MSGID_MOTOR_RESPONSE:
                        {
                            for(i=2;i<MSGLEN-2;i++)
                            {
                                motor_data[i] = msgbuffer[i];
                            }

                            //motor_data[3] = 3;

                            send_uart_message( motor_data );

                            break;
                        }
                        default:
                        {

                            break;
                        }
                    }

                    
                }
                case MSGT_I2C_DBG:
                {
                    // Here is where you could handle debugging, if you wanted
                    // keep track of the first byte received for later use (if desired)
                    last_reg_recvd = msgbuffer[0];
                    break;
                };
                case MSGT_I2C_RQST:
                {
                    // Generally, this is *NOT* how I recommend you handle an I2C slave request
                    // I recommend that you handle it completely inside the i2c interrupt handler
                    // by reading the data from a queue (i.e., you would not send a message, as is done
                    // now, from the i2c interrupt handler to main to ask for data).
                    //
                    // The last byte received is the "register" that is trying to be read
                    // The response is dependent on the register.

                    break;
                };
                default:
                {
                    // Your code should handle this error

                    // Sometimes the best course of action is to do nothing

                    break;
                };
            };
        }

        

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // Your code should handle this situation
            }
        } 
        else
        {
            unsigned char uart_response[UART_DATA_LENGTH];
            int jjj;
            for(jjj=0;jjj<UART_DATA_LENGTH;jjj++)
            {
                uart_response[jjj] = 0;
            }
            switch (msgtype)
            {

                case MSGT_TIMER1:
                {
                    
                    timer1_lthread(&t1thread_data, msgtype, length, msgbuffer);
                    break;
                };
                case MSGT_OVERRUN:
                {}
                case MSGT_UART_BAD_CHECKSUM:
                {                    
                    uart_response[0] = MSGID_UART_BAD_CHECKSUM; //Set Message ID
                    uart_response[1] = msgbuffer[0];
                    send_uart_message( uart_response );
                    break;
                }
                case MSGT_UART_BAD_COUNTER:
                {
                    uart_response[0] = MSGID_UART_BAD_COUNTER; //Set Message ID
                    uart_response[1] = msgbuffer[0];
                    uart_response[2] = msgbuffer[1];
                    send_uart_message( uart_response );
                    break;
                }
                case MSGT_UART_BAD_START:
                {
                    uart_response[0] = MSGID_UART_BAD_START; //Set Message ID
                    uart_response[1] = msgbuffer[0];
                    send_uart_message( uart_response );
                    break;
                }
                case MSGT_UART_BAD_END:
                {
                    uart_response[0] = MSGID_UART_BAD_END; //Set Message ID
                    uart_response[1] = msgbuffer[0];
                    send_uart_message( uart_response );
                    break;

                }
                case MSGT_UART_ACK_DATA:
                {
                    uart_response[0] = MSGID_UART_ACK; //Set Message ID
                    uart_response[1] = msgbuffer[0];
                    send_uart_message( uart_response );
                    break;

                }
                case MSGT_UART_DATA:
                {
                   
                    //uart_lthread(&uthread_data, msgtype, length, msgbuffer);


                    switch( msgbuffer[0] )
                    {
                        case MSGID_STATUS_REQUEST:
                        {

                            //send_uart_message( sensor_data );
                            break;
                        }
                        case MSGID_SENSOR_REQUEST:
                        {
                            send_uart_message( sensor_data );
                            break;
                        }
                        case MSGID_MOTOR_REQUEST:
                        {
                            send_uart_message( motor_data );
                            motor_data[1] = 0;
                            break;
                        }
                        case MSGID_MOVE:
                        {
                            // Copy msgbuffer over for timer 1 to deal with
                            for(i=0;i<UART_DATA_LENGTH;i++)
                            {
                                t1thread_data.move_msg[i] = msgbuffer[i];
                            }

                            t1thread_data.new_move_msg = 1;
                            
                            break;
                        }                        
                        default:
                        {
                            
                            break;
                        }


                    }

                    break;
                };
                default:
                {
                    // Your code should handle this error

                    // Sometimes the best course of action is to do nothing
                    
                    break;
                };
            };
        }
    }

}
void main (void)
{
	/*
		Define Variables ---------------------------------------------------------------------
	*/
	// I2C/MSG Q variables
	char c;		// Is this used?
	signed char	length;
	unsigned char	msgtype;
	unsigned char last_reg_recvd;
	i2c_comm ic;
	//unsigned char msgbuffer[MSGLEN+1];
	unsigned char msgbuffer[12];
	unsigned char i;
	int I2C_buffer[];
	int index = 0;
	int ITR = 0;
	int I2C_RX_MSG_COUNT = 0;
	int I2C_RX_MSG_PRECOUNT = 0;
	int I2C_TX_MSG_COUNT = 1;

	// Timer variables
	timer1_thread_struct t1thread_data; 	// info for timer1_lthread
	timer0_thread_struct t0thread_data; 	// info for timer0_lthread
	int timer_on = 1;
	int timer2Count0 = 0, timer2Count1 = 0;

	// UART variables
	uart_comm uc;
	//uart_thread_struct	uthread_data; 		// info for uart_lthread


	// ADC variables
	int ADCVALUE = 0;
	int adc_counter = 0;
	int adc_chan_num = 0;
	int adcValue = 0;
	int count = 0;

	// MIDI variable
	char notePlayed;

	/*
		Initialization ------------------------------------------------------------------------
	*/
	

	// Clock initialization
	OSCCON = 0x7C; // 16 MHz	// Use for internal oscillator	
	OSCTUNEbits.PLLEN = 1; 		// 4x the clock speed in the previous line
	
	
	// UART initialization
	init_uart_recv(&uc);		// initialize my uart recv handling code
	// configure the hardware USART device
  	Open2USART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT   & 
		USART_CONT_RX & USART_BRGH_LOW, 31);
	Open1USART( USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT   & 
		USART_CONT_RX & USART_BRGH_LOW, 51);

	//RCSTA1bits.CREN = 1;
	//RCSTA1bits.SPEN = 1;
	//TXSTA1bits.SYNC = 0;
	//PIE1bits.RC1IE = 1;
	IPR1bits.RC1IP = 0;
	
	// I2C/MSG Q initialization
	init_i2c(&ic);				// initialize the i2c code
	init_queues();				// initialize message queues before enabling any interrupts
	i2c_configure_slave(0x9E);	// configure the hardware i2c device as a slave

	// Timer initialization
	init_timer1_lthread(&t1thread_data);	// init the timer1 lthread
	OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_8);
	OpenTimer2( TIMER_INT_ON & T2_PS_1_16 /*& T2_8BIT_RW & T2_SOURCE_INT & T2_OSC1EN_OFF & T2_SYNC_EXT_OFF*/); // Turn Off
// ADC initialization
	// set up PORTA for input
	PORTA = 0x0;	// clear the port
	LATA = 0x0;		// clear the output latch
	TRISA = 0xFF;	// set RA3-RA0 to inputs
	ANSELA = 0xFF;	
	initADC();

	// Interrupt initialization
	// Peripheral interrupts can have their priority set to high or low
	// enable high-priority interrupts and low-priority interrupts
	enable_interrupts();
	// Decide on the priority of the enabled peripheral interrupts, 0 is low 1 is high
	IPR1bits.TMR1IP = 0;		// Timer1 interrupt
	//IPR1bits.RCIP = 0;			// USART RX interrupt
	IPR1bits.SSP1IP = 1;			// I2C interrupt
	PIE1bits.SSP1IE = 1;			// must specifically enable the I2C interrupts
	IPR1bits.ADIP = 1;			// ADC interrupt WE ADDED THIS

	
	// set direction for PORTB to output
	TRISB = 0x0;
	TRISD = 0xFF;
	LATB = 0x0;
	ANSELC = 0x00;


	/*
		Hand off messages to subroutines -----------------------------------------------------------
	*/
	// This loop is responsible for "handing off" messages to the subroutines
	// that should get them.  Although the subroutines are not threads, but
	// they can be equated with the tasks in your task diagram if you 
	// structure them properly.
  	while (1) {
		// Call a routine that blocks until either on the incoming
		// messages queues has a message (this may put the processor into
		// an idle mode
		block_on_To_msgqueues();
		/*
			High Priority MSGQ ----------------------------------------------------------------------
		*/
		
		// At this point, one or both of the queues has a message.  It 
		// makes sense to check the high-priority messages first -- in fact,
		// you may only want to check the low-priority messages when there
		// is not a high priority message.  That is a design decision and
		// I haven't done it here.
		length = ToMainHigh_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer);
		if (length < 0) {
			// no message, check the error code to see if it is concern
			if (length != MSGQUEUE_EMPTY) {
				//printf("Error: Bad high priority receive, code = %x\r\n", length);
			}
		} else {
			switch (msgtype) {
				case MSGT_ADC:	{				
					// Format I2C msg
					msgbuffer[6] = (timer2Count0 & 0x00FF);
					msgbuffer[5] = (timer2Count0 & 0xFF00) >> 8;
					msgbuffer[4] = (timer2Count1 & 0x00FF);
					msgbuffer[3] = (timer2Count1 & 0xFF00) >> 8;

					msgbuffer[8] = 0x00;
					msgbuffer[10] = adc_chan_num;
					msgbuffer[11] = 0xaa;			// ADC MSG opcode
					
					// Send I2C msg
					FromMainHigh_sendmsg(12, msgtype, msgbuffer);	// Send ADC msg to FromMainHigh MQ, which I2C
																	// int hdlr later Reads

					
					// Increment I2C message count from 1 to 100
					if(I2C_TX_MSG_COUNT < 100)	{
						I2C_TX_MSG_COUNT = I2C_TX_MSG_COUNT + 1;
					}
					else	{
						I2C_TX_MSG_COUNT = 1;
					}

					// Increment the channel number
					if(adc_chan_num <= 4)	adc_chan_num++;
					else	adc_chan_num = 0;
					// Set ADC channel based off of channel number
					if(adc_chan_num == 0)	SetChanADC(ADC_CH0);
					else if(adc_chan_num == 1)	SetChanADC(ADC_CH1);
					else if(adc_chan_num == 2)	SetChanADC(ADC_CH2);
					else if(adc_chan_num == 3)	SetChanADC(ADC_CH3);
					else if(adc_chan_num == 4)	SetChanADC(ADC_CH4);
					else	SetChanADC(ADC_CH5);
				};
				case MSGT_TIMER0: {
					timer0_lthread(&t0thread_data,msgtype,length,msgbuffer);

					break;
				};
				case MSGT_TIMER2:	{
					timer2Count0++;
					if(timer2Count0 >= 0xFFFF)	{	
						timer2Count1++;
						timer2Count0 = 0;
					}

					break;
				}

				case MSGT_I2C_DATA: { //this data still needs to be put in a buffer
;

						if(msgbuffer[0] == 0xaf)	{
						//FromMainLow_sendmsg(5, msgtype, msgbuffer);
						// The code below checks message 'counts' to see if any I2C messages were dropped
						//I2C_RX_MSG_COUNT = msgbuffer[4];
						
							FromMainLow_sendmsg(9, msgtype, msgbuffer);						
							TXSTA2bits.TXEN = 1;
	/*
							// Send note data to the MIDI device
							//while(Busy2USART());
							putc2USART(msgbuffer[1]);
							//while(Busy2USART());
							Delay1KTCYx(8);
							putc2USART(msgbuffer[2]);
							//while(Busy2USART());
							Delay1KTCYx(8);		
							putc2USART(msgbuffer[3]);
	*/
	
							if(I2C_RX_MSG_COUNT - I2C_RX_MSG_PRECOUNT == 1)	{
								if(I2C_RX_MSG_PRECOUNT < 99)	{
									I2C_RX_MSG_PRECOUNT++;
								}
								else	{
									I2C_RX_MSG_PRECOUNT = 0;
								}
							}
							else	{
								I2C_RX_MSG_PRECOUNT = I2C_RX_MSG_COUNT;
							}
						}
				};
				
	`			
				case MSGT_I2C_DBG: {
					//printf("I2C Interrupt received %x: ",msgtype);
					for (i=0;i<length;i++) {
						//printf(" %x",msgbuffer[i]);
					}
					//printf("\r\n");
					// keep track of the first byte received for later use
					last_reg_recvd = msgbuffer[0];
					break;
				};
				case MSGT_I2C_RQST: {
					//printf("I2C Slave Req\r\n");
					// The last byte received is the "register" that is trying to be read
					// The response is dependent on the register.
					switch (last_reg_recvd) {
						case 0xaa: {
							break;
						}
						/*
						case 0xa8: {
							length = 1;
							msgbuffer[0] = 0x3A;
							break;
						}					
						case 0xa9: {
							length = 1;
							msgbuffer[0] = 0xA3;
							break;
						}*/
					};
					//start_i2c_slave_reply(length,msgbuffer);
					break;
				};
				default: {
					//printf("Error: Unexpected msg in queue, type = %x\r\n", msgtype);
					break;
				};
			};
		}

		/*
			Low Priority MSGQ -----------------------------------------------------------------------
		*/
		
		length = ToMainLow_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer);
		if (length < 0) {
			// no message, check the error code to see if it is concern
			if (length != MSGQUEUE_EMPTY) {
			
			}
		} else {
			switch (msgtype) {
				
				case MSGT_TIMER1: {
					timer1_lthread(&t1thread_data,msgtype,length,msgbuffer);
					break;
				};
				case MSGT_OVERRUN:
				case MSGT_UART_DATA: 
				{
					LATB = 0xFF;
					msgbuffer[11] = 0xBB;
					FromMainHigh_sendmsg(12, msgtype, msgbuffer);
					
					break;
				};
				default: {
					
					break;
				};
			};
		}
 	 }
Esempio n. 4
0
void main(void) {
    char c;
    signed char length;
    unsigned char msgtype;
    unsigned char last_reg_recvd;
    uart_comm uc;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    unsigned char i;
    uart_thread_struct uthread_data; // info for uart_lthread
    timer1_thread_struct t1thread_data; // info for timer1_lthread
    timer0_thread_struct t0thread_data; // info for timer0_lthread

#ifdef __USE18F2680
    OSCCON = 0xFC; // see datasheet
    // We have enough room below the Max Freq to enable the PLL for this chip
    OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line
#else
#ifdef __USE18F45J10
    OSCCON = 0x82; // see datasheeet
    OSCTUNEbits.PLLEN = 1; // Makes the clock exceed the PIC's rated speed if the PLL is on 48 HZ
#else
#ifdef __USE18F26J50
    OSCCON = 0xE0; // see datasheeet
    OSCTUNEbits.PLLEN = 1;
#else
#ifdef __USE18F46J50
    OSCCON = 0xE0; //see datasheet
    OSCTUNEbits.PLLEN = 1;
#else
    Something is messed up.
    The PIC selected is not supported or the preprocessor directives are wrong.
#endif
#endif
#endif
#endif

    // initialize my uart recv handling code
    init_uart_recv(&uc);

    // initialize the i2c code
    init_i2c(&ic);

    // init the timer1 lthread
    init_timer1_lthread(&t1thread_data);

    // initialize message queues before enabling any interrupts
    init_queues();

#ifndef __USE18F26J50
    // set direction for PORTB to output
    PORTB = 0xFF;
    //TRISB = 0x0;
    //LATB = 0x0;
#endif

    // how to set up PORTA for input (for the V4 board with the PIC2680)
    /*
            PORTA = 0x0;	// clear the port
            LATA = 0x0;		// clear the output latch
            ADCON1 = 0x0F;	// turn off the A2D function on these pins
            // Only for 40-pin version of this chip CMCON = 0x07;	// turn the comparator off
            TRISA = 0x0F;	// set RA3-RA0 to inputs
     */

    // initialize Timers
    OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_EDGE_RISE & T0_SOURCE_EXT & T0_PS_1_1);
    OpenTimer1(TIMER_INT_ON& T1_SYNC_EXT_OFF  & T1_8BIT_RW & T1_SOURCE_EXT & T1_OSC1EN_OFF & T1_PS_1_1);
    //OpenTimer2(TIMER_INT_ON & T2_PS_1_16)
    
#ifdef __USE18F26J50
    // MTJ added second argument for OpenTimer1()
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);
#else
#ifdef __USE18F46J50
   // OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);
#else
    //OpenTimer1(TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
#endif
#endif

    // Decide on the priority of the enabled peripheral interrupts
    // 0 is low, 1 is high
    // Timer1 interrupt
    IPR1bits.TMR1IP = 0;
    // USART RX interrupt
    IPR1bits.RCIP = 0;
    // I2C interrupt
    IPR1bits.SSPIP = 1;

    // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D)
#if 1
    // Note that the temperature sensor Address bits (A0, A1, A2) are also the
    // least significant bits of LATB -- take care when changing them
    // They *are* changed in the timer interrupt handlers if those timers are
    //   enabled.  They are just there to make the lights blink and can be
    //   disabled.
    i2c_configure_slave(0x9E);
#else
    // If I want to test the temperature sensor from the ARM, I just make
    // sure this PIC does not have the same address and configure the
    // temperature sensor address bits and then just stay in an infinite loop
    i2c_configure_slave(0x9A);
#ifdef __USE18F2680
    LATBbits.LATB1 = 1;
    LATBbits.LATB0 = 1;
    LATBbits.LATB2 = 1;
#endif
    for (;;);
#endif

    // must specifically enable the I2C interrupts
    PIE1bits.SSPIE = 1;

    // configure the hardware USART device
#ifdef __USE18F26J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
#ifdef __USE18F46J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x26);


    //Low  & 0x26 for 48Mhz
    //High & 0x26
#endif
#endif

    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();

    /* Junk to force an I2C interrupt in the simulator (if you wanted to)
    PIR1bits.SSPIF = 1;
    _asm
    goto 0x08
    _endasm;
     */
     
    // printf() is available, but is not advisable.  It goes to the UART pin
    // on the PIC and then you must hook something up to that to view it.
    // It is also slow and is blocking, so it will perturb your code's operation
    // Here is how it looks: printf("Hello\r\n");
   

    // loop forever
    // This loop is responsible for "handing off" messages to the subroutines
    // that should get them.  Although the subroutines are not threads, but
    // they can be equated with the tasks in your task diagram if you
    // structure them properly.

    TRISCbits.RC0 = 1;
    while (1) {
        // Call a routine that blocks until either on the incoming
        // messages queues has a message (this may put the processor into
        // an idle mode)
        block_on_To_msgqueues();

        // At this point, one or both of the queues has a message.  It
        // makes sense to check the high-priority messages first -- in fact,
        // you may only want to check the low-priority messages when there
        // is not a high priority message.  That is a design decision and
        // I haven't done it here.
        length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
                case MSGT_TIMER0:
                {
                    timer0_lthread(&t0thread_data, msgtype, length, msgbuffer);
                    break;
                };
                case MSGT_I2C_DATA:
                {
                  break;
                };
                case MSGT_I2C_DBG:
                {
                    // Here is where you could handle debugging, if you wanted
                    // keep track of the first byte received for later use (if desired)
                    last_reg_recvd = msgbuffer[0];
                    break;
                };
                case MSGT_I2C_RQST:
                {
                    // Generally, this is *NOT* how I recommend you handle an I2C slave request
                    // I recommend that you handle it completely inside the i2c interrupt handler
                    // by reading the data from a queue (i.e., you would not send a message, as is done
                    // now, from the i2c interrupt handler to main to ask for data).
                    //
                    // The last byte received is the "register" that is trying to be read
                    // The response is dependent on the register.
                    start_i2c_slave_reply(length, msgbuffer);
                    break;
                };
                case MSGT_MOTOR_COMMAND:
                {
                    motor_lthread(msgtype,length,msgbuffer);
                  break;
                };
                case MSGT_MOTOR_STOP:
                {
                    motor_lthread(msgtype,length,msgbuffer);
                    break;
                };
                case MSGT_UART_SEND:
                {
                    uart_lthread(&uthread_data,msgtype,length,msgbuffer);
                     break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // Your code should handle this situation
            }
        } else {
            switch (msgtype) {
                case MSGT_PARSE:
                {
                    //parser_lthread(msgtype,length,msgbuffer);
                  break;  
                };
                case MSGT_OVERRUN:
                case MSGT_UART_DATA:
                {
                    uart_lthread(&uthread_data, msgtype, length, msgbuffer);
                    break;
                };
                
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }
    }

}
Esempio n. 5
0
void main(void) {
    char c;
    int count = 0;
    signed char length;
    unsigned char msgtype;
    unsigned char last_reg_recvd;
    uart_comm uc;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    unsigned char i;
    uart_thread_struct uthread_data; // info for uart_lthread
    timer1_thread_struct t1thread_data; // info for timer1_lthread
    timer0_thread_struct t0thread_data; // info for timer0_lthread


    unsigned char config1 = 0x00, config2 = 0x00, portconfig = 0x00;

#ifdef __USE18F2680
    OSCCON = 0xFC; // see datasheet
    // We have enough room below the Max Freq to enable the PLL for this chip
    OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line
#else
#ifdef __USE18F45J10
    OSCCON = 0x82; // see datasheeet
    OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on
#else
#ifdef __USE18F26J50
    OSCCON = 0xE0; // see datasheeet
    OSCTUNEbits.PLLEN = 1;
#else
#ifdef __USE18F46J50
    OSCCON = 0xE0; //see datasheet
    OSCTUNEbits.PLLEN = 1;
#else
    Something is messed up.
            The PIC selected is not supported or the preprocessor directives are wrong.
#endif
#endif
#endif
#endif


            // initialize my uart recv handling code
            init_uart_recv(&uc);

    // initialize the   code
    init_i2c(&ic);

    // init the timer1 lthread
    init_timer1_lthread(&t1thread_data);

    // initialize message queues before enabling any interrupts
    init_queues();

#ifndef __USE18F26J50
    //    // set direction for PORTB to output
    //    TRISB = 0x0;
    //    LATB = 0x0;
#endif
    PORTB = 0xFF;
    // Setup PORTBs for debug pins.
    TRISBbits.RB1 = 0;
    TRISBbits.RB2 = 0;
    TRISBbits.RB3 = 0;
    TRISBbits.RB4 = 0;
    TRISBbits.RB5 = 0;
    LATBbits.LATB1 = 0;
    LATBbits.LATB2 = 0;
    LATBbits.LATB3 = 0;
    LATBbits.LATB4 = 0;
    LATBbits.LATB5 = 0;

    //line sensor
    PORTD = 0x0;
    LATD = 0x0;
    TRISD3 = 0x1;
    TRISD4 = 0x1;
    TRISD5 = 0x1;
    TRISD6 = 0x1;
    TRISD7 = 0x1;




    // initialize Timers
    OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_EXT & T0_PS_1_1);

#ifdef __USE18F26J50
    // MTJ added second argument for OpenTimer1()
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF, 0x0);
#else
#ifdef __USE18F46J50
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF, 0x0);
#else
    OpenTimer1(TIMER_INT_ON & T1_PS_1_1 & T1_16BIT_RW & T1_SOURCE_EXT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
    WriteTimer1(0xFFCF);
#endif
#endif



    // Decide on the priority of the enabled peripheral interrupts
    // 0 is low, 1 is high
    // Timer1 interrupt
    IPR1bits.TMR1IP = 0;
    // USART TX interrupt
    IPR1bits.TXIP = 0;
    // I2C interrupt
    IPR1bits.SSPIP = 1;

    // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D)
#if 1
    // Note that the temperature sensor Address bits (A0, A1, A2) are also the
    // least significant bits of LATB -- take care when changing them
    // They *are* changed in the timer interrupt handlers if those timers are
    //   enabled.  They are just there to make the lights blink and can be
    //   disabled.
    i2c_configure_slave(0x9E);
#else
    // If I want to test the temperature sensor from the ARM, I just make
    // sure this PIC does not have the same address and configure the
    // temperature sensor address bits and then just stay in an infinite loop
    i2c_configure_slave(0x9A);
#ifdef __USE18F2680
    LATBbits.LATB1 = 1;
    LATBbits.LATB0 = 1;
    LATBbits.LATB2 = 1;
#endif
    for (;;);
#endif

    // must specifically enable the I2C interrupts
    PIE1bits.SSPIE = 1;
    PIE1bits.RCIE = 1;

    // configure the hardware USART device
#ifdef __USE18F26J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
#ifdef __USE18F46J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
    // Configuration Details:
    // Solve for SPBRG = ((48Mhz/19200)/16)-1 = 155
    // Calculated Baud Rate = 48MHz / (4*(624 + 1)) = 19200
    // Error (19200 - 19200) / 19200 = 0
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_HIGH, 39);
    BAUDCONbits.BRG16 = 0;
    RCSTAbits.SPEN = 1;
    RCSTAbits.CREN = 1;
#endif
#endif


    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();


    // loop forever
    // This loop is responsible for "handing off" messages to the subroutines
    // that should get them.  Although the subroutines are not threads, but
    // they can be equated with the tasks in your task diagram if you
    // structure them properly.
    while (1) {



        // Call a routine that blocks until either on the incoming
        // messages queues has a message (this may put the processor into
        // an idle mode)
        block_on_To_msgqueues();

        // At this point, one or both of the queues has a message.  It
        // makes sense to check the high-priority messages first -- in fact,
        // you may only want to check the low-priority messages when there
        // is not a high priority message.  That is a design decision and
        // I haven't done it here.
        length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {

                case MSGT_I2C_DATA:
                {
                    uart_lthread(&uthread_data, msgtype, length, msgbuffer);
                    break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
    }
}
Esempio n. 6
0
void main(void) {
    //char c;
    signed char length;
    unsigned char msgtype;
    unsigned char last_reg_recvd;
    uart_comm uc;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    //    unsigned char to_send_buffer[MAX_I2C_SENSOR_DATA_LEN + HEADER_MEMBERS];
    //    uint8 to_send_len;
    //    int data_points_count = 0;
    //unsigned char i;
    //uart_thread_struct uthread_data; // info for uart_lthread
    //timer1_thread_struct t1thread_data; // info for timer1_lthread
    //timer0_thread_struct t0thread_data; // info for timer0_lthread

#ifdef __USE18F2680
    OSCCON = 0xFC; // see datasheet
    // We have enough room below the Max Freq to enable the PLL for this chip
    OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line
#else
#ifdef __USE18F45J10
    OSCCON = 0x82; // see datasheeet
    OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on
#else
#ifdef __USE18F26J50
    OSCCON = 0xE0; // see datasheeet
    OSCTUNEbits.PLLEN = 1;
#else
#ifdef __USE18F46J50
    OSCCON = 0xE0; //see datasheet
    OSCTUNEbits.PLLEN = 1;
#else
    Something is messed up.
            The PIC selected is not supported or the preprocessor directives are wrong.
#endif
#endif
#endif
#endif

            // initialize my uart recv handling code

    init_uart_recv(&uc);

    // initialize the i2c code
    init_i2c(&ic);

    // init the timer1 lthread
    //    init_timer1_lthread(&t1thread_data);

    // initialize message queues before enabling any interrupts
    init_queues();

#ifndef __USE18F26J50
    // set direction for PORTB to output
#ifndef MOTOR_PIC
    TRISB = 0x0;
    LATB = 0x0;
#else
    TRISBbits.RB0 = 0;
    TRISBbits.RB1 = 0;
    TRISBbits.RB2 = 0;
    TRISBbits.RB3 = 0;
#endif

#endif

    // how to set up PORTA for input (for the V4 board with the PIC2680)
    /*
            PORTA = 0x0;	// clear the port
            LATA = 0x0;		// clear the output latch
            ADCON1 = 0x0F;	// turn off the A2D function on these pins
            // Only for 40-pin version of this chip CMCON = 0x07;	// turn the comparator off
            TRISA = 0x0F;	// set RA3-RA0 to inputs
     */
    // initialize Timers
#ifndef MASTER_PIC
#ifdef SENSOR_PIC
    OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_16);
    INTCONbits.T0IE = 1;
#elif !defined(MOTOR_PIC)
    OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_4);
#else
    OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_PS_1_1 & T0_SOURCE_EXT);
#endif
#else
    OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_16);
#endif

#ifdef __USE18F26J50
    // MTJ added second argument for OpenTimer1()
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF, 0x0);
#else
#ifdef __USE18F46J50
    //OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF, 0x0);
#else
#ifndef MOTOR_PIC
//    OpenTimer1(TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
#else
    OpenTimer1(TIMER_INT_ON & T1_PS_1_1 & T1_16BIT_RW & T1_SOURCE_EXT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
    WRITETIMER1(0xFFE8); // leave in here, encoder's for motor 2 doesn't work without it
#endif
#endif
#endif

    
    // Decide on the priority of the enabled peripheral interrupts
    // 0 is low, 1 is high
    //Timer0 interrupt
    INTCON2bits.TMR0IP = 1;
    // Timer1 interrupt
#ifdef SENSOR_PIC
//    IPR1bits.TMR1IP = 0;
#else
    IPR1bits.TMR1IP = 1;
#endif
    // USART RX interrupt
    IPR1bits.RCIP = 0;
    IPR1bits.TXIP = 0;
    // I2C interrupt
    IPR1bits.SSPIP = 1;

    //set i2c int high
    PIE1bits.SSPIE = 1;



#ifdef SENSOR_PIC
    //resetAccumulators();
    init_adc();
    initUS();

    // must specifically enable the I2C interrupts
    IPR1bits.ADIP = 0;
    
    // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D)
    i2c_configure_slave(SENSOR_ADDR << 1); //address 0x10
#elif defined MOTOR_PIC
    i2c_configure_slave(MOTOR_ADDR << 1); //address 0x20
#elif defined PICMAN
    i2c_configure_slave(PICMAN_ADDR << 1); //address 0x10,different bus from sensor
#elif defined I2C_MASTER
    //sending clock frequency
    i2c_configure_master(); //12MHz clock set hardcoded
#endif

#ifdef MASTER_PIC
    ///////Color Sensor Interrupt//////////
    TRISBbits.TRISB0 = 1;
    ANCON1bits.PCFG12 = 1; //not sure which is port b
    INTCONbits.INT0IE = 1;
    INTCON2bits.INTEDG0 = 0;
    INTCONbits.INT0IF = 0;
    initializeColorSensor();
    ///////////////////////////////////////

#endif


    // configure the hardware USART device
#ifdef __USE18F26J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
#ifdef __USE18F46J50

#ifndef MOTOR_PIC
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_LOW, 38);
#else
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_LOW, 0x19);
#endif

#else
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_HIGH, 38);
    //    BAUDCONbits.BRG16 = 1;
    //    TXSTAbits.TXEN = 1;
    //    RCSTAbits.SPEN = 1;
    //    RCSTAbits.CREN = 1;
#endif
#endif

    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();
    LATBbits.LB7 = 0;
#ifndef MASTER_PIC
    LATBbits.LB0 = 0;
#endif
    LATBbits.LB1 = 0;
    LATBbits.LB2 = 0;
    LATBbits.LB3 = 0;
    WRITETIMER0(0x00FF);
    

    // loop forever
    // This loop is responsible for "handing off" messages to the subroutines
    // that should get them.  Although the subroutines are not threads, but
    // they can be equated with the tasks in your task diagram if you
    // structure them properly.
    while (1) {
        // Call a routine that blocks until either on the incoming
        // messages queues has a message (this may put the processor into
        // an idle mode)
        block_on_To_msgqueues();

        //We have a bunch of queues now - ToMainHigh, ToMainLow, FromMainHigh, FromMainLow,
        //FromUARTInt, and FromI2CInt
        //From queues are most important because they will be called repeatedly with busy info
        //Int queues are second because we'll often get data from either UART or I2C
        //ToMain are least

        length = FromMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
#ifdef I2C_MASTER
                case MSGT_MASTER_RECV_BUSY:
                {
                    //retry
                    //debugNum(4);
                    i2c_master_recv(msgbuffer[0]);
                    break;
                };
                case MSGT_MASTER_SEND_BUSY:
                {
                    //retry
                    //debugNum(8);
                    i2c_master_send(msgbuffer[0], length - 1, msgbuffer + 1); // point to second position (actual msg start)
                    break;
                };
                case MSGT_MASTER_SEND_NO_RAW_BUSY:
                {
                    i2c_master_send_no_raw(msgbuffer[0], length-1, msgbuffer + 1);
                };
                case MSGT_TURN_CHECK:
                {
                    //check IR sensors
                    unsigned char frame[FRAME_MEMBERS] = {0};
                    packFrame(frame, sizeof frame);
                    //frame[1] is ir1 and frame[2] is ir2
                    frame[1] = 1;//just for now, provide these dummy values
                    frame[2] = 1;
                    if((frame[1] > frame[2]) && (frame[1] - frame[2]) > 10){
                        //readjust right
                        char out[HEADER_MEMBERS] = {0};
                        uint8 len = generateReadjustCW(out, sizeof out, I2C_COMM);
                        i2c_master_send(MOTOR_ADDR, len, out);
                        // no need to call waitForSensorFrame() again
                    }
                    else if((frame[2] > frame[1]) && (frame[2] - frame[1]) > 10){
                        //readjust left
                        char out[HEADER_MEMBERS] = {0};
                        uint8 len = generateReadjustCCW(out, sizeof out, I2C_COMM);
                        i2c_master_send(MOTOR_ADDR, len, out);
                        // no need to call waitForSensorFrame() again
                    }
                    else{
                        char command[HEADER_MEMBERS] = {0};
                        uint8 len = generateTurnCompleteReq(command, sizeof command, UART_COMM); //tell picman turn complete
                        uart_send_array(command, len);
                        turnCompleted();
                    }
                };
#endif
                case MSGT_UART_TX_BUSY:
                {
                    // TODO: take out for now
                    uart_send_array(msgbuffer, length);
                    break;
                };
                default:
                    break;
            }
        }

        length = FromUARTInt_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
                case MSGT_OVERRUN:
                    break;
                case MSGT_UART_DATA:
                {
#ifdef PICMAN
                    setRoverDataLP(msgbuffer);
                    handleRoverDataLP();
#elif defined(MASTER_PIC) || defined(ROVER_EMU)
                    setBrainDataLP(msgbuffer); //pass data received and tell will pass over i2c
                    handleMessageLP(UART_COMM, I2C_COMM); //sends the response and then sets up the command handling
#endif
                    break;
                };
                case MSGT_UART_RECV_FAILED:
                {
                    debugNum(2);
                    debugNum(4);
                    debugNum(2);
                    debugNum(4);
                    break;
                };
                case MSGT_UART_TX_BUSY:
                {
                    // TODO: take out for now
                    uart_send_array(msgbuffer, length);
                    break;
                };
                default:
                    break;
            }
        }

        length = FromI2CInt_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
                case MSGT_I2C_DATA:
                {
#if defined(MASTER_PIC) || defined(ARM_EMU)
                    //handle whatever data will come through via i2c
                    //msgbuffer can hold real data - error codes will be returned through the error cases
                    setRoverDataLP(msgbuffer);
                    handleRoverDataLP();
#else
                    setBrainDataLP(msgbuffer);
#endif
                    break;
                };
                case MSGT_I2C_RQST:
                {
#if defined(MOTOR_PIC) || defined(SENSOR_PIC)
                    handleMessageLP(I2C_COMM, I2C_COMM);
#elif defined(PICMAN)
                    handleMessageLP(I2C_COMM, UART_COMM);
#endif
                    break;
                };
                case MSGT_I2C_DBG:
                {
                    // Here is where you could handle debugging, if you wanted
                    // keep track of the first byte received for later use (if desired)
                    last_reg_recvd = msgbuffer[0];
                    break;
                };
#ifdef MASTER_PIC
                case MSGT_I2C_MASTER_RECV_FAILED:
                {
                    uart_send_array(msgbuffer, length);
                    break;
                };
                case MSGT_I2C_MASTER_SEND_FAILED:
                {
                    uart_send_array(msgbuffer, length);
                    break;
                };
                case MSGT_MASTER_RECV_BUSY:
                {
                    //retry
//                    debugNum(4);
                    i2c_master_recv(msgbuffer[0]);
                    break;
                };
                case MSGT_MASTER_SEND_BUSY:
                {
                    //retry
//                    debugNum(8);
                    i2c_master_send(msgbuffer[0], length - 1, msgbuffer + 1); // point to second position (actual msg start)
                    break;
                };
                case MSGT_COLOR_SENSOR_INIT:
                {
                    initializeColorSensorStage();
                };
#endif
                default:
                    break;
            }
        }





        length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
                case MSGT_TIMER0:
                {
                    //timer0_lthread(&t0thread_data, msgtype, length, msgbuffer);
                    break;
                };
                    //                #ifdef I2C_MASTER
                    //                case MSGT_MASTER_RECV_BUSY:
                    //                {
                    //                    //retry
                    //                    debugNum(4);
                    //                    i2c_master_recv(msgbuffer[0]);
                    //                    break;
                    //                };
                    //                case MSGT_MASTER_SEND_BUSY:
                    //                {
                    //                    //retry
                    //                    debugNum(8);
                    //                    i2c_master_send(msgbuffer[0], length-1, msgbuffer + 1); // point to second position (actual msg start)
                    //                    break;
                    //                };
                    //                #endif
                    //                case MSGT_I2C_DATA:
                    //                {
                    //                    debugNum(4);
                    //#if defined(MASTER_PIC) || defined(ARM_EMU)
                    //                    //handle whatever data will come through via i2c
                    //                    //msgbuffer can hold real data - error codes will be returned through the error cases
                    //                    setRoverDataLP(msgbuffer);
                    //                    handleRoverDataLP();
                    //#else
                    //                    setBrainDataLP(msgbuffer);
                    //#endif
                    //                    debugNum(4);
                    //                    break;
                    //                };
                    //                case MSGT_I2C_RQST:
                    //                {
                    //#if defined(MOTOR_PIC) || defined(SENSOR_PIC)
                    //                    handleMessageLP(I2C_COMM, I2C_COMM);
                    //#elif defined(PICMAN)
                    //                    handleMessageLP(I2C_COMM, UART_COMM);
                    //#endif
                    //                    break;
                    //                };
                    //                case MSGT_I2C_DBG:
                    //                {
                    //                    // Here is where you could handle debugging, if you wanted
                    //                    // keep track of the first byte received for later use (if desired)
                    //                    last_reg_recvd = msgbuffer[0];
                    //                    break;
                    //                };
                    //#ifdef MASTER_PIC
                    //                case MSGT_I2C_MASTER_RECV_FAILED:
                    //                {
                    //                    uart_send_array(msgbuffer, length);
                    //                    break;
                    //                };
                    //                case MSGT_I2C_MASTER_SEND_FAILED:
                    //                {
                    //                    uart_send_array(msgbuffer, length);
                    //                    break;
                    //                };
                    //#endif
                case MSGT_AD:
                {
#ifdef SENSOR_PIC
                    //addDataPoints(sensorADid, msgbuffer, length);
#endif
                    break;
                };

                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // Your code should handle this situation
            }
        } else {
            switch (msgtype) {
                case MSGT_AD:
                {
#ifdef SENSOR_PIC
                    //addDataPoints(sensorADid, msgbuffer, length);
#endif
                    break;
                };
                case MSGT_TIMER1:
                {
                    //timer1_lthread(&t1thread_data, msgtype, length, msgbuffer);
                    break;
                };
                    //                case MSGT_OVERRUN:
                    //                    break;
                    //                case MSGT_UART_DATA:
                    //                {
                    //#ifdef PICMAN
                    //                    setRoverDataLP(msgbuffer);
                    //                    handleRoverDataLP();
                    //#elif defined(MASTER_PIC) || defined(ROVER_EMU)
                    //                    setBrainDataLP(msgbuffer);//pass data received and tell will pass over i2c
                    //                    handleMessageLP(UART_COMM, I2C_COMM); //sends the response and then sets up the command handling
                    //#endif
                    //                    break;
                    //                };
                    //                case MSGT_UART_RECV_FAILED:
                    //                {
                    //                    debugNum(1);
                    //                    debugNum(2);
                    //                    debugNum(1);
                    //                    debugNum(2);
                    //                    break;
                    //                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }
    }
//
}
Esempio n. 7
0
// This program 
//   (1) prints to the UART and it reads from the UART
//   (2) it "prints" what it reads from the UART to portb (where LEDs are connected)
//   (3) it uses two timers to interrupt at different rates and drive 2 LEDs (on portb)
void main (void)
{
	char c;
	int adcVal;
	signed char	length;
	unsigned char	msgtype;
	unsigned char last_reg_recvd, action;
	uart_comm uc;
	i2c_comm ic;
	unsigned char msgbuffer[MSGLEN+1];
	unsigned char i;
	uart_thread_struct	uthread_data; // info for uart_lthread
	timer1_thread_struct t1thread_data; // info for timer1_lthread
	timer0_thread_struct t0thread_data; // info for timer0_lthread
	initADC();
	// set to run really, really fast...
	OSCCON = 0x6C; // 4 MHz
	OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line

	// initialize my uart recv handling code
	init_uart_recv(&uc);

	// initialize the i2c code
	init_i2c(&ic);

	// init the timer1 lthread
	init_timer1_lthread(&t1thread_data);

	// initialize message queues before enabling any interrupts
	init_queues();

	// set direction for PORTB to output
	TRISB = 0x0;
	LATB = 0x0;

	// set up PORTA for input
/*
	PORTA = 0x0;	// clear the port
	LATA = 0x0;		// clear the output latch
	ADCON1 = 0x0F;	// turn off the A2D function on these pins
	// Only for 40-pin version of this chip CMCON = 0x07;	// turn the comparator off
	TRISA = 0x0F;	// set RA3-RA0 to inputs
*/

	// initialize Timers
	OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_128);
	OpenTimer1( TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
	
	// Peripheral interrupts can have their priority set to high or low
	// enable high-priority interrupts and low-priority interrupts
	enable_interrupts();

	// Decide on the priority of the enabled peripheral interrupts
	// 0 is low, 1 is high
	// Timer1 interrupt
	IPR1bits.TMR1IP = 0;
	// USART RX interrupt
	IPR1bits.RCIP = 0;
	// I2C interrupt
	IPR1bits.SSPIP = 1;

	// configure the hardware i2c device as a slave
	i2c_configure_slave(0x8A);

	// must specifically enable the I2C interrupts
	PIE1bits.SSPIE = 1;

	// configure the hardware USART device
  	OpenUSART( USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT   & 
		USART_CONT_RX & USART_BRGH_LOW, 0x19);

/* Junk to force an I2C interrupt in the simulator
PIR1bits.SSPIF = 1;
_asm
goto 0x08
_endasm;
*/

	printf("Hello\r\n");
	// loop forever
	// This loop is responsible for "handing off" messages to the subroutines
	// that should get them.  Although the subroutines are not threads, but
	// they can be equated with the tasks in your task diagram if you 
	// structure them properly.
  	while (1) {
		// Call a routine that blocks until either on the incoming
		// messages queues has a message (this may put the processor into
		// an idle mode
		block_on_To_msgqueues();

		// At this point, one or both of the queues has a message.  It 
		// makes sense to check the high-priority messages first -- in fact,
		// you may only want to check the low-priority messages when there
		// is not a high priority message.  That is a design decision and
		// I haven't done it here.
		length = ToMainHigh_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer);
		if (length < 0) {
			// no message, check the error code to see if it is concern
			if (length != MSGQUEUE_EMPTY) {
				printf("Error: Bad high priority receive, code = %x\r\n",
					length);
			}
		} else {
			switch (msgtype) {
				case MSGT_TIMER0: {
					timer0_lthread(&t0thread_data,msgtype,length,msgbuffer);
					break;
				};
				case MSGT_I2C_DATA:
				case MSGT_I2C_DBG: {
					printf("I2C Interrupt received %x: ",msgtype);
					for (i=0;i<length;i++) {
						printf(" %x",msgbuffer[i]);
					}
					//LATBbits.LATB0 = !LATBbits.LATB0;
					LATB = msgbuffer[2];
					//LATB = msgtype;
					//LATB=0x01;
					//printf("\r\n");
					// keep track of the first byte received for later use
					//last_reg_recvd = msgbuffer[0];
					//action=msgbuffer[7];
					//msgbuffer[0]=0xff;
					//msgbuffer[1]=0xff;
					//msgbuffer[2]=0xff;
					//msgbuffer[3]=0xff;
					//start_i2c_slave_reply(4,msgbuffer);
					break;
				};
				case MSGT_I2C_RQST: {
					printf("I2C Slave Req\r\n");
					
					length=2;
					msgbuffer[0]=(adcVal>>8)&0xff;
					msgbuffer[1]=adcVal&0xff;
					
					///	msgbuffer[0]=0x55;
					//			msgbuffer[1]=0x55;
								//printf("XXX: type: %x ADC: %x MsgB1: %x MsgB2: %x\r\n",msgtype,value,msgbuffer[0],msgbuffer[1]);
								//break;
					//		}
					//}
					start_i2c_slave_reply(length,msgbuffer);
					break;
				};
				default: {
					printf("Error: Unexpected msg in queue, type = %x\r\n",
						msgtype);
					break;
				};
			};
			readADC(&adcVal);
		}

		// Check the low priority queue
		length = ToMainLow_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer);
		if (length < 0) {
			// no message, check the error code to see if it is concern
			if (length != MSGQUEUE_EMPTY) {
				printf("Error: Bad low priority receive, code = %x\r\n",
					length);
			}
		} else {
			switch (msgtype) {
				case MSGT_TIMER1: {
					timer1_lthread(&t1thread_data,msgtype,length,msgbuffer);
					break;
				};
				case MSGT_OVERRUN:
				case MSGT_UART_DATA: {
					uart_lthread(&uthread_data,msgtype,length,msgbuffer);
					break;
				};
				default: {
					printf("Error: Unexpected msg in queue, type = %x\r\n",
						msgtype);
					break;
				};
			};
		}
 	 }

}
Esempio n. 8
0
void main(void) {
    char c;
    signed char length;
    unsigned char msgtype;
    unsigned char last_reg_recvd;
    uart_comm uc;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    unsigned char i;
    uart_thread_struct uthread_data; // info for uart_lthread
    timer1_thread_struct t1thread_data; // info for timer1_lthread
    timer0_thread_struct t0thread_data; // info for timer0_lthread

#ifdef __USE18F2680
    OSCCON = 0xFC; // see datasheet
    // We have enough room below the Max Freq to enable the PLL for this chip
    OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line
#else
#ifdef __USE18F45J10
    OSCCON = 0x82; // see datasheeet
    OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on
#else
#ifdef __USE18F26J50
    OSCCON = 0xE0; // see datasheeet
    OSCTUNEbits.PLLEN = 1;
#else
#ifdef __USE18F46J50
    OSCCON = 0xE0; //see datasheet
    OSCTUNEbits.PLLEN = 1;
#else
    Something is messed up.
    The PIC selected is not supported or the preprocessor directives are wrong.
#endif
#endif
#endif
#endif

    // initialize my uart recv handling code
    init_uart_recv(&uc);

    // initialize the i2c code
    init_i2c(&ic);

    // init the timer1 lthread
    init_timer1_lthread(&t1thread_data);

    // initialize message queues before enabling any interrupts
    init_queues();

#ifndef __USE18F26J50
    // set direction for PORTB to output
    TRISB = 0xFF; //input
    LATB = 0x0;

    PORTA = 0x0;
    LATA = 0x0;
    TRISA = 0x0F;
#endif

    // how to set up PORTA for input (for the V4 board with the PIC2680)
    /*
            PORTA = 0x0;	// clear the port
            LATA = 0x0;		// clear the output latch
            ADCON1 = 0x0F;	// turn off the A2D function on these pins
            // Only for 40-pin version of this chip CMCON = 0x07;	// turn the comparator off
            TRISA = 0x0F;	// set RA3-RA0 to inputs
     */

    // initialize Timers

#ifdef MOTORPIC  
    OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_EXT & T0_EDGE_RISE & T0_PS_1_1);   
#else
    OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_64);
#endif
    
#ifdef __USE18F26J50
    // MTJ added second argument for OpenTimer1()
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);
#else
#ifdef __USE18F46J50
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);
#else
    OpenTimer1(TIMER_INT_ON & T1_8BIT_RW & T1_PS_1_1 & T1_SOURCE_EXT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
    TRISC = 0xFF; // C as input
#endif
#endif

    // Decide on the priority of the enabled peripheral interrupts
    // 0 is low, 1 is high

    // ADC interrupt
    IPR1bits.ADIP = 0;
    PIE1bits.ADIE = 1;
    // Timer1 interrupt
    IPR1bits.TMR1IP = 0;
    // Timer0 interrupt
    INTCON2bits.TMR0IP = 1;
    // USART RX interrupt
    IPR1bits.RCIP = 0;
    // USART TX interrupt
    IPR1bits.TXIP = 0;
    // I2C interrupt
    IPR1bits.SSPIP = 1;

    // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D)
#if 1
    // Note that the temperature sensor Address bits (A0, A1, A2) are also the
    // least significant bits of LATB -- take care when changing them
    // They *are* changed in the timer interrupt handlers if those timers are
    //   enabled.  They are just there to make the lights blink and can be
    //   disabled.

#ifdef I2CMASTER
    i2c_configure_master();
#else
#ifdef SENSORPIC
    i2c_configure_slave(0x9E); // slave addr 4F
#else
#ifdef MOTORPIC
    i2c_configure_slave(0xBE); // slave addr 5F
#endif
#endif
#endif
    
#else
    // If I want to test the temperature sensor from the ARM, I just make
    // sure this PIC does not have the same address and configure the
    // temperature sensor address bits and then just stay in an infinite loop
    i2c_configure_slave(0x9A);
#ifdef __USE18F2680
    LATBbits.LATB1 = 1;
    LATBbits.LATB0 = 1;
    LATBbits.LATB2 = 1;
#endif
    for (;;);
#endif

    // must specifically enable the I2C interrupts
    PIE1bits.SSPIE = 1;

    // configure the hardware USART device
#ifdef __USE18F26J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
#ifdef __USE18F46J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
    OpenUSART(USART_TX_INT_ON & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_HIGH, 38);
    RCSTAbits.SPEN = 1;
    TRISC = 0xFF;
    
#endif
#endif

    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();

    /* Junk to force an I2C interrupt in the simulator (if you wanted to)
    PIR1bits.SSPIF = 1;
    _asm
    goto 0x08
    _endasm;
     */

    // printf() is available, but is not advisable.  It goes to the UART pin
    // on the PIC and then you must hook something up to that to view it.
    // It is also slow and is blocking, so it will perturb your code's operation
    // Here is how it looks: printf("Hello\r\n");

      OpenADC(ADC_FOSC_16 & ADC_LEFT_JUST & ADC_2_TAD,
          ADC_CH1 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS,
          0b1011);
      SetChanADC(ADC_CH1);
      


     // ADC_CALIB();

    // loop forever
    // This loop is responsible for "handing off" messages to the subroutines
    // that should get them.  Although the subroutines are not threads, but
    // they can be equated with the tasks in your task diagram if you
    // structure them properly.
      unsigned char msg[2] = {0x01, 0x02};
     //i2c_master_send(1, 5, msg, 0x9E); // send length, recv length, message and address + r/w bit (0)
      //i2c_master_recv();
      
      //uart_trans(2, msg);
      //WriteUSART(0xAA);


    while (1) {
        // Call a routine that blocks until either on the incoming
        // messages queues has a message (this may put the processor into
        // an idle mode)
        block_on_To_msgqueues();

        // At this point, one or both of the queues has a message.  It
        // makes sense to check the high-priority messages first -- in fact,
        // you may only want to check the low-priority messages when there
        // is not a high priority message.  That is a design decision and
        // I haven't done it here.
        length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
                case MSGT_TIMER0:
                {
                    timer0_lthread(&t0thread_data, msgtype, length, msgbuffer);
                    break;
                };
                case MSGT_I2C_DATA:
                case MSGT_I2C_DBG:
                {
                    // Here is where you could handle debugging, if you wanted
                    // keep track of the first byte received for later use (if desired)
                    last_reg_recvd = msgbuffer[0];
                    break;
                };
                case MSGT_I2C_MASTER_RECV_COMPLETE:
                {
                    //msgbuffer[0] = length;
                    
                    uart_trans(length, msgbuffer);
                    
                    //i2c_master_send(1, 5, msg, 0x9E);
                    break;
                };
                case MSGT_I2C_MASTER_RECV_FAILED:
                {
                    //unsigned char msg2[2] = {0xEE, 0xFF};
                    //i2c_master_send(1, 5, msg, 0x9E);
                    //LATBbits.LATB2 = 0;
                    break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // Your code should handle this situation
            }
        } else {
            switch (msgtype) {
                case MSGT_TIMER1:
                {
                    timer1_lthread(&t1thread_data, msgtype, length, msgbuffer);
                    break;
                };
                case MSGT_OVERRUN:
                case MSGT_UART_DATA:
                {
                    //uart_trans(2, msgbuffer);
                    
                    if(msgbuffer[0] == 0xBA){
                        // motor command
                        i2c_master_send(5, 5, msgbuffer, 0xBE);
                    } else if(msgbuffer[0] == 0xAA){
                        // sensor command
                        i2c_master_send(1, 5, msgbuffer, 0x9E);
                    }
                    
                    LATBbits.LATB2 = 0;
                    //uart_lthread(&uthread_data, msgtype, length, msgbuffer);
                    break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }
    }

}
Esempio n. 9
0
void main(void) {
    char c;
    signed char length;
    unsigned char msgtype;
    int test_var = 0;
    unsigned char SENSOR_TYPE_REQUESTED;
    uart_comm uc;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    unsigned char i;
    uart_thread_struct uthread_data; // info for uart_lthread
    timer1_thread_struct t1thread_data; // info for timer1_lthread
    timer0_thread_struct t0thread_data; // info for timer0_lthread
    char count = 0;

#ifdef __USE18F2680
    OSCCON = 0xFC; // see datasheet
    // We have enough room below the Max Freq to enable the PLL for this chip
    OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line
#else
    OSCCON = 0x82; // see datasheeet
    OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on
#endif

    // initialize my uart recv handling code
    init_uart_recv(&uc);

    // initialize the i2c code
    init_i2c(&ic);

    // init the timer1 lthread
   init_timer1_lthread(&t1thread_data);

    // initialize message queues before enabling any interrupts
    init_queues();

    // set direction for PORTB to output
    TRISB = 0x0;
    LATB = 0x0;

    // how to set up PORTA for input (for the V4 board with the PIC2680)
    /*
            PORTA = 0x0;	// clear the port
            LATA = 0x0;		// clear the output latch
            ADCON1 = 0x0F;	// turn off the A2D function on these pins
            // Only for 40-pin version of this chip CMCON = 0x07;	// turn the comparator off
            TRISA = 0x0F;	// set RA3-RA0 to inputs
     */

    // initialize Timers
    //OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_128);
    OpenTimer1(TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
 //    WriteTimer1(65086);

    i2c_configure_slave(0x2A);


   
     

    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();

    // Decide on the priority of the enabled peripheral interrupts
    // 0 is low, 1 is high
    // Timer1 interrupt
    IPR1bits.TMR1IP = 0;
    // USART RX interrupt
 //   IPR1bits.RCIP = 1;
    // USART TX interrupt
 //   IPR1bits.TXIP = 0;
    // I2C interrupt
    IPR1bits.SSPIP = 1;

   //  OpenUSART( USART_TX_INT_OFF & USART_RX_INT_ON &  USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX  & USART_BRGH_HIGH & USART_ADDEN_OFF, 38);
    //38 gives us baud rate of approx 19230

    //enable rx interrupts
  //   PIE1bits.RCIE = 1;
 //   PIE1bits.TXIE = 0; //disable send interrupt until we have something in mesage queue

    //i2c interrupt enable
    PIE1bits.SSPIE = 1;



  OpenADC( ADC_FOSC_16 & ADC_RIGHT_JUST & ADC_4_TAD, ADC_CH0 & ADC_INT_ON
                & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, ADC_0ANA);

    // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D)
#if 1
    // Note that the temperature sensor Address bits (A0, A1, A2) are also the
    // least significant bits of LATB -- take care when changing them
    // They *are* changed in the timer interrupt handlers if those timers are
    //   enabled.  They are just there to make the lights blink and can be
    //   disabled.
  //  i2c_configure_slave(0x9E);
#else
    // If I want to test the temperature sensor from the ARM, I just make
    // sure this PIC does not have the same address and configure the
    // temperature sensor address bits and then just stay in an infinite loop
    i2c_configure_slave(0x9A);
    LATBbits.LATB1 = 1;
    LATBbits.LATB0 = 1;
    LATBbits.LATB2 = 1;
    for (;;);
#endif

    // must specifically enable the I2C interrupts
  //  PIE1bits.SSPIE = 1;

    // configure the hardware USART device
   // OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
     //       USART_CONT_RX & USART_BRGH_LOW, 0x19);

    /* Junk to force an I2C interrupt in the simulator (if you wanted to)
    PIR1bits.SSPIF = 1;
    _asm
    goto 0x08
    _endasm;
     */

    // printf() is available, but is not advisable.  It goes to the UART pin
    // on the PIC and then you must hook something up to that to view it.
    // It is also slow and is blocking, so it will perturb your code's operation
    // Here is how it looks: printf("Hello\r\n");


    // loop forever
    // This loop is responsible for "handing off" messages to the subroutines
    // that should get them.  Although the subroutines are not threads, but
    // they can be equated with the tasks in your task diagram if you
    // structure them properly.
    while (1) {
        // Call a routine that blocks until either on the incoming
        // messages queues has a message (this may put the processor into
        // an idle mode)
        block_on_To_msgqueues();

        // At this point, one or both of the queues has a message.  It
        // makes sense to check the high-priority messages first -- in fact,
        // you may only want to check the low-priority messages when there
        // is not a high priority message.  That is a design decision and
        // I haven't done it here.
        length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
                case MSGT_TIMER0:
                {
                    timer0_lthread(&t0thread_data, msgtype, length, msgbuffer);
                    break;
                };
                case MSGT_I2C_DATA:
                case MSGT_I2C_DBG:
                {
                    // Here is where you could handle debugging, if you wanted
                    // keep track of the first byte received for later use (if desired)
                    SENSOR_TYPE_REQUESTED = msgbuffer[0];
                    

                    break;
                };
                case MSGT_I2C_RQST:
                {
                    // Generally, this is *NOT* how I recommend you handle an I2C slave request
                    // I recommend that you handle it completely inside the i2c interrupt handler
                    // by reading the data from a queue (i.e., you would not send a message, as is done
                    // now, from the i2c interrupt handler to main to ask for data).
                    //
                    // The last byte received is the "register" that is trying to be read
                    // The response is dependent on the register.
                   /* switch (SENSOR_TYPE_REQUESTED) {
                        case LASER_DATA_REQUEST: //laser type
                        {


                            break;
                        }
                        case INFRARED_DATA_REQUEST:
                        {
                            length = 4; //place infrared data here
                            msgbuffer[0] = 0x42;
                            msgbuffer[1] = 0x43;
                            msgbuffer[2] = 0x44;
                            msgbuffer[3] = 0x45;

                            break;
                        }
                        default:
                        {
                            length = 1;
                            msgbuffer[0] = 0xFF;
                            break;
                        }
                    };
                   /* msgbuffer[0] = 0x77;
                    msgbuffer[1] = 0x66;
                    msgbuffer[2] = 0x54*/

                    length = 6;
                    msgbuffer[0] = 30;
                    msgbuffer[1] = 33+count;
                    msgbuffer[2] = 40;
                    msgbuffer[3] = 43+count;
                    msgbuffer[4] = 44+count;
                    msgbuffer[5] = 45+count;

                    count++;

                    start_i2c_slave_reply(length, msgbuffer);
                    break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // Your code should handle this situation
            }
        } else {
            switch (msgtype) {
                case MSGT_TIMER1:
                {
                    timer1_lthread(&t1thread_data, msgtype, length, msgbuffer);
                    break;
                };
                case MSGT_OVERRUN:
                case MSGT_UART_DATA:
                {
                    uart_lthread(&uthread_data, msgtype, length, msgbuffer);
                    break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }
    }

}
Esempio n. 10
0
void main (void)
{

unsigned int counter=0,curval=0;
char c;
signed char	length, adlength;
unsigned char	msgtype;
unsigned char last_reg_recvd, action;
unsigned char adbuffer[2];
uart_comm uc;
i2c_comm ic;
unsigned char msgbuffer[MSGLEN+1];
unsigned char i;
uart_thread_struct	uthread_data; // info for uart_lthread
timer1_thread_struct t1thread_data; // info for timer1_lthread
timer0_thread_struct t0thread_data; // info for timer0_lthread
unsigned char data;
TRISB = 0b00000011;
TRISA = 0x0;
TRISC=0b00010000;
MIWICS=1;

glcdInit();

	OSCCON = 0x6C; // 4 MHz
	OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line

	// initialize my uart recv handling code
//	init_uart_recv(&uc);

	// initialize the i2c code
//s	init_i2c(&ic);

	// init the timer1 lthread
	init_timer1_lthread(&t1thread_data);

	// initialize message queues before enabling any interrupts
	init_queues();

	// set direction for PORTB to output
//	TRISB = 0x0;
//	LATB = 0x0;


	// set up PORTA for input
/*
	PORTA = 0x0;	// clear the port
	LATA = 0x0;		// clear the output latch
	ADCON1 = 0x0F;	// turn off the A2D function on these pins
	// Only for 40-pin version of this chip CMCON = 0x07;	// turn the comparator off
	TRISA = 0x0F;	// set RA3-RA0 to inputs
*/

	// initialize Timers
	OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_4);
//	OpenTimer1( TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW  & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0);
	
	// Peripheral interrupts can have their priority set to high or low
	// enable high-priority interrupts and low-priority interrupts
	enable_interrupts();

	// Decide on the priority of the enabled peripheral interrupts
	// 0 is low, 1 is high
	// Timer1 interrupt
	IPR1bits.TMR1IP = 0;
	// USART RX interrupt
	IPR1bits.RCIP = 0;
	// I2C interrupt
	IPR1bits.SSPIP = 1;

	// configure the hardware i2c device as a slave
//	i2c_configure_slave(0x8A);

	// must specifically enable the I2C interrupts
	PIE1bits.SSPIE = 1;

	// configure the hardware USART device
  	/*OpenUSART( USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT   & 
		USART_CONT_RX & USART_BRGH_LOW, 0x19);*/
while(1)
{

	block_on_To_msgqueues();

		// At this point, one or both of the queues has a message.  It 
		// makes sense to check the high-priority messages first -- in fact,
		// you may only want to check the low-priority messages when there
		// is not a high priority message.  That is a design decision and
		// I haven't done it here.
		length = ToMainHigh_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer);
		
		if (length < 0) {
			// no message, check the error code to see if it is concern
			if (length != MSGQUEUE_EMPTY) {
				printf("Error: Bad high priority receive, code = %x\r\n",
					length);
			}
		} else {
			switch (msgtype) {
				case MSGT_TIMER0: {
					timer0_lthread(&t0thread_data,msgtype,length,msgbuffer);
					break;
				};
				case MSGT_I2C_DATA:
				case MSGT_I2C_DBG: {
					printf("I2C Interrupt received %x: ",msgtype);
					for (i=0;i<length;i++) {
						printf(" %x",msgbuffer[i]);
					}
					//LATBbits.LATB0 = !LATBbits.LATB0;
					LATB = msgbuffer[2];
					//LATB = msgtype;
					//LATB=0x01;
					//printf("\r\n");
					// keep track of the first byte received for later use
					//last_reg_recvd = msgbuffer[0];
					//action=msgbuffer[7];
					//msgbuffer[0]=0xff;
					//msgbuffer[1]=0xff;
					//msgbuffer[2]=0xff;
					//msgbuffer[3]=0xff;
					//start_i2c_slave_reply(4,msgbuffer);
					break;
				};
				case MSGT_I2C_RQST: {
					printf("I2C Slave Req\r\n");
					length=2;
				/*	if(counter==0)
					{
						msgbuffer[0]=0x55;
						msgbuffer[1]=0x55;
						counter++;
					}else
					{
						msgbuffer[0]=0x22;
						msgbuffer[1]=0x22;
						counter=0;
					}*/
				/*	adlength = 	ADQueue_recvmsg(2,0x55,(void *)&adbuffer);
					if((adlength==MSGQUEUE_EMPTY) || (adlength==MSGBUFFER_TOOSMALL))
					{
						msgbuffer[0]=0xff;
						msgbuffer[1]=0xff;
						//msgbuffer[2]=0xff;
					}
					else
					{					
						msgbuffer[0]=adbuffer[0];
						msgbuffer[1]=adbuffer[1];
					//	msgbuffer[0]=0x22;
					//	msgbuffer[1]=0x22;
					}*/
				//	LATB=msgbuffer[0];
								//printf("XXX: type: %x ADC: %x MsgB1: %x MsgB2: %x\r\n",msgtype,value,msgbuffer[0],msgbuffer[1]);
								//break;
					//		}
					//}
					start_i2c_slave_reply(length,msgbuffer);
					break;
				};
				case MSGT_LCD_AREA1:{
				DEBUG_LED1=1;
				DEBUG_LED2=0;
				DEBUG_LED3=0;
				};
				break;
				case MSGT_LCD_AREA2:{
				DEBUG_LED1=0;
				DEBUG_LED2=1;
				DEBUG_LED3=0;
				};
				break;
				case MSGT_LCD_AREA3:{
				DEBUG_LED1=1;
				DEBUG_LED2=1;
				DEBUG_LED3=0;
				};
				break;
				case MSGT_LCD_AREA4:{
				DEBUG_LED1=0;
				DEBUG_LED2=0;
				DEBUG_LED3=1;
				};
				break;
				case MSGT_LCD_TOUCH:{
				DEBUG_LED1=0;
				DEBUG_LED2=0;
				DEBUG_LED3=0;
				};
				break;
				case MSGT_LCD_NOTOUCH:{	
					DEBUG_LED1=0;
					DEBUG_LED2=0;
					DEBUG_LED3=0;
				};
				break;
				default: {
					printf("Error: Unexpected msg in queue, type = %x\r\n",
						msgtype);
					break;
				};
			};
		}

		// Check the low priority queue
		length = ToMainLow_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer);
		if (length < 0) {
			// no message, check the error code to see if it is concern
			if (length != MSGQUEUE_EMPTY) {
				printf("Error: Bad low priority receive, code = %x\r\n",
					length);
			}
		} else {
			switch (msgtype) {
				case MSGT_TIMER1: {
					timer1_lthread(&t1thread_data,msgtype,length,msgbuffer);
					break;
				};
				case MSGT_OVERRUN:
				case MSGT_UART_DATA: {
					uart_lthread(&uthread_data,msgtype,length,msgbuffer);
					break;
				};
				default: {
					printf("Error: Unexpected msg in queue, type = %x\r\n",
						msgtype);
					break;
				};
			};
		}
/*curval=counter%4;
counter++;
if(curval==0)
{

	writePixelByte(0xf5,CS1);
}
else
{
	writePixelByte(0x0,CS2);
}*/

/*if(curval==0)
{
	data=0b01010101;
	printSPIHeader(OLATA, data);
}
else if(curval==1)
{
	data=0b10101010;
	printSPIHeader(OLATA, data);
}
else if(curval==2)
{
	data=0b01010101;
	printSPIHeader(OLATB, data);
}
else
{
	data=0b10101010;
	printSPIHeader(OLATB, data);
	counter=0;
}

X_PLUS=1;//touchscreen voltage
X_MINUS=1;
Y_PLUS=0;
//Y_MINUS=1;
//LATB=LATB|0xf;
readADC2(&adcVal); //detect a touch

if(adcVal>0x300) //touch threshold
	{

		X_PLUS=1;//touchscreen voltage
		X_MINUS=0;
		readADC2(&adcVal); //read a touch Y location
		if(adcVal <0x0f0)
		{
			LATCbits.LATC0=1;
			LATCbits.LATC1=0;
			LATCbits.LATC2=0;
		}
		else if(adcVal<0x1f0)
		{
			LATCbits.LATC0=0;
			LATCbits.LATC1=1;
			LATCbits.LATC2=0;
		}
		else if(adcVal<0x2f0)
		{
			LATCbits.LATC0=1;
			LATCbits.LATC1=1;
			LATCbits.LATC2=0;
		}
		else 
		{
			LATCbits.LATC0=0;
			LATCbits.LATC1=0;
			LATCbits.LATC2=1;
		}
	}else
	{
		LATCbits.LATC0=0;
		LATCbits.LATC1=0;
		LATCbits.LATC2=0;
	}*/

}

}
Esempio n. 11
0
int main(void) {
    char c;
    signed char length;
    unsigned char msgtype;
    unsigned char msgbuffer[MSGLEN + 1];
    unsigned char i;

    ANSELA = 0x0; // Set to Digital Function
    ANSELB = 0x0;
    ANSELC = 0x0;
    ANSELD = 0x0;
    ANSELE = 0x0;

    UART_DATA uart_data1;
    UART_DATA uart_data2;
    TIMER_DATA TIMER1;
    timer_init(&TIMER1);

    UART1_Init(&uart_data1);
    UART2_Init(&uart_data2);

    TRISAbits.TRISA0 = 0; // Set PIN A as output
    TRISAbits.TRISA1 = 0;
    TRISAbits.TRISA2 = 0; // Set PIN A as output
    TRISAbits.TRISA3 = 0;

    TRISAbits.TRISA4 = 0; // Set PIN A as output
    TRISAbits.TRISA5 = 0;
    TRISAbits.TRISA6 = 0; // Set PIN A as output
    TRISAbits.TRISA7 = 0;

    LATAbits.LATA1 = 0; //Set PIN for Stepper motor low
    // initialize message queues before enabling any interrupts
    init_queues();

    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();

    laser_init();

    /* Junk to force an I2C interrupt in the simulator (if you wanted to)
       PIR1bits.SSPIF = 1;
       _asm
       goto 0x08
       _endasm;
     */

    // printf() is available, but is not advisable.  It goes to the UART pin
    // on the PIC and then you must hook something up to that to view it.
    // It is also slow and is blocking, so it will perturb your code's operation
    // Here is how it looks: printf("Hello\r\n");


    // loop forever
    // This loop is responsible for "handing off" messages to the subroutines
    // that should get them.  Although the subroutines are not threads, but
    // they can be equated with the tasks in your task diagram if you
    // structure them properly.
    while (1) {
        // Call a routine that blocks until either on the incoming
        // messages queues has a message (this may put the processor into
        // an idle mode)
        block_on_To_msgqueues();

        // At this point, one or both of the queues has a message.  It
        // makes sense to check the high-priority messages first -- in fact,
        // you may only want to check the low-priority messages when there
        // is not a high priority message.  That is a design decision and
        // I haven't done it here.
        length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
                case MSGT_LASER_READ:
                {
                    ReadLaser_Message(msgbuffer, length);
                    break;
                };
                case MSGT_WIFLY_RECIEVE:
                {
                    ReadWIFLY_Message(msgbuffer,length);
                    break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // Your code should handle this situation
            }


        } else {
            switch (msgtype) {
                case MSGT_TIMER0:
                {
                    Timer_message_handle();
                    break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }
    }

}