Exemple #1
0
int timer1_lthread(timer1_thread_struct *tptr, int msgtype, int length, unsigned char *msgbuffer) {
    tptr->msgcount++;
    // Every tenth message we get from timer1 we
    // send something to the High Priority Interrupt
    if ((tptr->msgcount % 100) == 0) {
#ifdef MASTERPIC
        //ToMainLow_sendmsg(0, MSGT_ADC_DATA, (void*) 0);
        ToMainHigh_sendmsg(0, MSGT_POLL_PICS, (void*) 0);
#endif
        tptr->msgcount = 0;
    }
#ifdef MASTERPIC
    else if ((tptr->msgcount % 50) == 0)
    {
        ToMainHigh_sendmsg(0, MSGT_POLL_FLINE, (void*) 0);
        
    }
#endif
#ifdef MASTERPIC
    else if ((tptr->msgcount % 20) == 0)
    {
        ToMainHigh_sendmsg(0, MSGT_POLL_ENCDRS, (void*) 0);
        //tptr->msgcount = 0;
    }

#endif

}
void timer0_int_handler() {
    // Encoder count for motor 0.
    timer0Counter++;
    // Reset the timer
    WriteTimer0(0xCF);

    DEBUG_ON(TMR0_DBG);
    DEBUG_OFF(TMR0_DBG);

    if (ticks_flag) {
        // Reverse counter to prevent it from going a set distance.
        ticks0Counter++;
        // Going thru right hand turn
        if (ticks0Counter >= maxTickZero && postRight == 1) {
            postRight = 2;
            WriteUSART(0x00);
            // Turn right 90
            motorBuffer[0] = 0x01;
            motorBuffer[1] = 0x03;
            motorBuffer[2] = 0x04;
            motorBuffer[3] = 0x01;
            motorBuffer[4] = 0x0C;
            motorBuffer[5] = 0x09;

            ToMainHigh_sendmsg(MOTORLEN, MSGT_I2C_DATA, (void *) motorBuffer);
        } else if (ticks0Counter >= maxTickZero && postRight == 2) {
            // Move forward after right turn
            postRight = 0;

            motorBuffer[0] = 0x01;
            motorBuffer[1] = 0x03;
            motorBuffer[2] = 0x01;
            motorBuffer[3] = 0x01;
            motorBuffer[4] = 0x00;
            motorBuffer[5] = 0x00;

            ToMainHigh_sendmsg(MOTORLEN, MSGT_I2C_DATA, (void *) motorBuffer);
        } else if (ticks0Counter >= maxTickZero && postAlignFlag) {
            postAlignFlag = 0;
            motorBuffer[0] = 0x01;
            motorBuffer[1] = 0x03;
            motorBuffer[2] = 0x01;
            motorBuffer[3] = 0x01;
            motorBuffer[4] = 0x00;
            motorBuffer[5] = 0x00;

            ToMainHigh_sendmsg(MOTORLEN, MSGT_I2C_DATA, (void *) motorBuffer);
        } else if (ticks0Counter >= maxTickZero) {
            //Stops wheels after set number of ticks
            WriteUSART(0x00);
        }
    }
}
Exemple #3
0
void uart_recv_int_handler() {
    if (DataRdyUSART()) {
        char i = 0;
        uc_ptr->buffer[uc_ptr->buflen] = ReadUSART();
        
        uc_ptr->buflen++;
        
        // check if a message should be sent
        if (uc_ptr->buflen == MAXUARTBUF) {
#ifdef MASTERPIC
            ToMainLow_sendmsg(uc_ptr->buflen, MSGT_UART_DATA, (void *) uc_ptr->buffer);
#else
            PORTCbits.RC1 = 1;
            
            ToMainHigh_sendmsg(uc_ptr->buflen, MSGT_UART_RFID, (void *) uc_ptr->buffer);
#endif
            uc_ptr->buflen = 0;
        }
    }
    if (USART_Status.OVERRUN_ERROR == 1) {
        // we've overrun the USART and must reset
        // send an error message for this
        RCSTAbits.CREN = 0;
        RCSTAbits.CREN = 1;
        ToMainLow_sendmsg(0, MSGT_OVERRUN, (void *) 0);
    }
}
Exemple #4
0
void adc_int_handler()
{
    unsigned int result;
    result = ReadADC();
    result = result /4;
    ToMainHigh_sendmsg(sizeof(result),MSGT_I2C_DATA_SAVE,(void *)&result);
}
int motor_control_thread(motor_control_thread_struct *mptr, int msgtype, int length, unsigned char *msgbuffer) {
    
    #if ENABLE_GPIO
        MAIN_THREAD = 0;
        MOTOR_CONTROL_THREAD = 1;
    #endif
    //int i = 0;
       // motor_direction = msgbuffer[0];
      //  time = msgbuffer[1];
       // magnitude = msgbuffer[2];

    /*    testbuffer[counter] = msgbuffer[0];
        testbuffer[counter+1] = msgbuffer[1];
        testbuffer[counter+2] = msgbuffer[2];
        counter = counter + 3;
        if (counter == 45)
            counter = 0;*/

       ToMainHigh_sendmsg(3,MSGT_I2C_MASTER_SEND, msgbuffer);
    #if ENABLE_GPIO
        MAIN_THREAD = 1;
        MOTOR_CONTROL_THREAD = 0;
    #endif





    
}
// ADC interrupt hdlr
// This interrupt is drivin high every time the ADC conversion is complete
void adc_int_handler()	{
	unsigned char val[3];

	// Read ADC, then store the values into message buffer
	val[0] = ADRESH;
	val[1] = ADRESL;
	
	// Read the timer to determine when the ADC was read
	val[2] = ReadTimer1();

	ToMainHigh_sendmsg(3, MSGT_ADC, (void *) val);	// Send ADC value to ToMainHigh MSGQ
	PIR1bits.ADIF = 0;								// Reset the ADC interrupt

}
Exemple #7
0
void timer0_int_handler() {
    unsigned int val;
    int length, msgtype;

    // toggle an LED
    LATBbits.LATB0 = !LATBbits.LATB0;
    // reset the timer
    WriteTimer0(0);
    // try to receive a message and, if we get one, echo it back
    length = FromMainHigh_recvmsg(sizeof(val), (unsigned char *)&msgtype, (void *) &val);
    if (length == sizeof (val)) {
        ToMainHigh_sendmsg(sizeof (val), MSGT_TIMER0, (void *) &val);
    }
}
Exemple #8
0
void displayDebug(void)
{
	char printUser[]="User  ", printOpt[]="Opt   ", blank[]=" ";
	unsigned char buffer[3]={MSGT_USER_CHOICE,chosenName,chosenState};
	
	ToMainHigh_sendmsg(3,MSGT_USER_CHOICE,(void *) buffer);
	setPos(0,0);
	setStartLine(0);
	printUser[5]=(char)chosenName+0x40;
	printOpt[5]=(char)chosenState+0x40;
	drawString(printUser,1);
	drawString(printOpt,2);
	drawString(blank,3);
	drawString(blank,4);
}
Exemple #9
0
void i2c_master_int_handler(){
    switch (ic_ptr->status){
        // Page 183 - I2C Master Mode Waveform (Transfer)
        case (I2C_MASTER_SEND_STARTED): {
            ic_ptr->status = I2C_MASTER_SEND_START;
            SSPBUF = ((ic_ptr->slave_addr << 1) & 0xFE);
            break;
        }
        case (I2C_MASTER_SEND_START): {
            if (SSPCON2bits.ACKSTAT == 0) {
                if (ic_ptr->outbufind < ic_ptr->outbuflen) {
                    SSPBUF = ic_ptr->outbuffer[ic_ptr->outbufind];
                    ic_ptr->outbufind++;
                    ic_ptr->status = I2C_MASTER_SEND_START;
                }
                else {
                    ToMainHigh_sendmsg(0, MSGT_I2C_MASTER_SEND_COMPLETE, 0);
                    ic_ptr->outbuflen = 0;
                    ic_ptr->status = I2C_IDLE;
                    SSPCON2bits.PEN = 1;
                }
            }
            else {
                ToMainHigh_sendmsg(0, MSGT_I2C_MASTER_SEND_FAILED, 0);
                ic_ptr->status = I2C_IDLE;
                SSPCON2bits.PEN = 1;
            }
            break;
        }
        case (I2C_MASTER_SEND_DONE): {
            ToMainHigh_sendmsg(0, MSGT_I2C_MASTER_SEND_COMPLETE, 0);
            ic_ptr->status = I2C_IDLE;
            break;
        }

        // Master receive

        case I2C_MASTER_RECV_STARTED: {
            //flipDBG(1);
                ic_ptr->status = I2C_MASTER_RECV_SET_RCEN;
                SSPBUF = ((ic_ptr->slave_addr << 1) | 0x01) & 0xFF;
                break;
        }
        case I2C_MASTER_RECV_SET_RCEN: {
            if (SSPCON2bits.ACKSTAT == 0) {
                //flipDBG(1);
                ic_ptr->status = I2C_MASTER_RECV_DATA;
                SSPCON2bits.RCEN = 1;
            }
            else {
                ToMainHigh_sendmsg(0, MSGT_I2C_MASTER_RECV_FAILED, 0);
                ic_ptr->status = I2C_IDLE;
                SSPCON2bits.PEN = 1;
            }
            break;
        }
        case I2C_MASTER_RECV_DATA: {
            //flipDBG(1);
            //    if (SSPSTATbits.BF == 1) {
                    ic_ptr->buffer[ic_ptr->bufind] = SSPBUF;
                    ic_ptr->bufind++;
                    ic_ptr->status = I2C_MASTER_RECV_ACK;
           //     }
                if (ic_ptr->bufind < ic_ptr->buflen) {
                    SSPCON2bits.ACKDT = 0;
                    SSPCON2bits.ACKEN = 1;
                }
                else {
                    SSPCON2bits.ACKDT = 1;
                    SSPCON2bits.ACKEN = 1;
                }
            break;
        }
        case I2C_MASTER_RECV_ACK: {
            if (ic_ptr->bufind < ic_ptr->buflen) {
                ic_ptr->status = I2C_MASTER_RECV_DATA;
                SSPCON2bits.RCEN = 1;
            }
            else {
                if(ic_ptr->slave_addr == 0x4F)
                {ToMainLow_sendmsg(ic_ptr->buflen, MSGT_MOTOR_BACK, (void *)(ic_ptr->buffer));}
                else
                {ToMainLow_sendmsg(ic_ptr->buflen, MSGT_SEND_BACK, (void *)(ic_ptr->buffer));}
                
                ic_ptr->status = I2C_IDLE;
                SSPCON2bits.PEN = 1;
                SSPCON2bits.ACKDT = 0;
                SSPCON2bits.ACKEN = 1;
            }
            break;
        }
    }
}
Exemple #10
0
void i2c_slave_int_handler() {
    unsigned char i2c_data;
    unsigned char data_read = 0;
    unsigned char data_written = 0;
    unsigned char msg_ready = 0;
    unsigned char msg_to_send = 0;
    unsigned char overrun_error = 0;
    unsigned char error_buf[3];

    // clear SSPOV
    if (SSPCON1bits.SSPOV == 1) {
        SSPCON1bits.SSPOV = 0;
        // we failed to read the buffer in time, so we know we
        // can't properly receive this message, just put us in the
        // a state where we are looking for a new message
        ic_ptr->status = I2C_IDLE;
        overrun_error = 1;
        ic_ptr->error_count++;
        ic_ptr->error_code = I2C_ERR_OVERRUN;
    }
    // read something if it is there
    if (SSPSTATbits.BF == 1) {
        i2c_data = SSPBUF;
        data_read = 1;
    }

    if (!overrun_error) {
        switch (ic_ptr->status) {
            case I2C_IDLE:
            {
                // ignore anything except a start
                if (SSPSTATbits.S == 1) {
                    handle_start(data_read);
                    // if we see a slave read, then we need to handle it here
                    if (ic_ptr->status == I2C_SLAVE_SEND) {
                        data_read = 0;
                        msg_to_send = 1;
                    }
                }
                break;
            }
            case I2C_STARTED:
            {
                // in this case, we expect either an address or a stop bit
                if (SSPSTATbits.P == 1) {
                    // we need to check to see if we also read an
                    // address (a message of length 0)
                    ic_ptr->event_count++;
                    if (data_read) {
                        if (SSPSTATbits.D_A == 0) {
                            msg_ready = 1;
                        } else {
                            ic_ptr->error_count++;
                            ic_ptr->error_code = I2C_ERR_NODATA;
                        }
                    }
                    ic_ptr->status = I2C_IDLE;
                } else if (data_read) {
                    ic_ptr->event_count++;
                    if (SSPSTATbits.D_A == 0) {
                        if (SSPSTATbits.R_W == 0) { // slave write
                            ic_ptr->status = I2C_RCV_DATA;
                        } else { // slave read
                            ic_ptr->status = I2C_SLAVE_SEND;
                            msg_to_send = 1;
                            // don't let the clock stretching bit be let go
                            data_read = 0;
                        }
                    } else {
                        ic_ptr->error_count++;
                        ic_ptr->status = I2C_IDLE;
                        ic_ptr->error_code = I2C_ERR_NODATA;
                    }
                }
                break;
            }
            case I2C_SLAVE_SEND:
            {
                if (ic_ptr->outbufind < ic_ptr->outbuflen) {
                    SSPBUF = ic_ptr->outbuffer[ic_ptr->outbufind];
                    ic_ptr->outbufind++;
                    data_written = 1;
                } else {
                    // we have nothing left to send
                    ic_ptr->status = I2C_IDLE;
                }
                break;
            }
            case I2C_RCV_DATA:
            {
                // we expect either data or a stop bit or a (if a restart, an addr)
                if (SSPSTATbits.P == 1) {
                    // we need to check to see if we also read data
                    ic_ptr->event_count++;
                    if (data_read) {
                        if (SSPSTATbits.D_A == 1) {
                            ic_ptr->buffer[ic_ptr->buflen] = i2c_data;
                            ic_ptr->buflen++;
                            msg_ready = 1;
                        } else {
                            ic_ptr->error_count++;
                            ic_ptr->error_code = I2C_ERR_NODATA;
                            ic_ptr->status = I2C_IDLE;
                        }
                    } else {
                        msg_ready = 1;
                    }
                    ic_ptr->status = I2C_IDLE;
                } else if (data_read) {
                    ic_ptr->event_count++;
                    if (SSPSTATbits.D_A == 1) {
                        ic_ptr->buffer[ic_ptr->buflen] = i2c_data;
                        ic_ptr->buflen++;
                    } else /* a restart */ {
                        if (SSPSTATbits.R_W == 1) {
                            ic_ptr->status = I2C_SLAVE_SEND;
                            msg_ready = 1;
                            msg_to_send = 1;
                            // don't let the clock stretching bit be let go
                            data_read = 0;
                        } else { /* bad to recv an address again, we aren't ready */
                            ic_ptr->error_count++;
                            ic_ptr->error_code = I2C_ERR_NODATA;
                            ic_ptr->status = I2C_IDLE;
                        }
                    }
                }
                break;
            }
        }
    }

    // release the clock stretching bit (if we should)
    if (data_read || data_written) {
        // release the clock
        if (SSPCON1bits.CKP == 0) {
            SSPCON1bits.CKP = 1;
        }
    }

    // must check if the message is too long, if
    if ((ic_ptr->buflen > MAXI2CBUF - 2) && (!msg_ready)) {
        ic_ptr->status = I2C_IDLE;
        ic_ptr->error_count++;
        ic_ptr->error_code = I2C_ERR_MSGTOOLONG;
    }

    if (msg_ready) {
        ic_ptr->buffer[ic_ptr->buflen] = ic_ptr->event_count;
        ToMainHigh_sendmsg(ic_ptr->buflen + 1, MSGT_I2C_DATA, (void *) ic_ptr->buffer);
        ic_ptr->buflen = 0;
    } else if (ic_ptr->error_count >= I2C_ERR_THRESHOLD) {
        error_buf[0] = ic_ptr->error_count;
        error_buf[1] = ic_ptr->error_code;
        error_buf[2] = ic_ptr->event_count;
        ToMainHigh_sendmsg(sizeof (unsigned char) *3, MSGT_I2C_DBG, (void *) error_buf);
        ic_ptr->error_count = 0;
    }
    if (msg_to_send) {
        // send to the queue to *ask* for the data to be sent out

        start_i2c_slave_reply(I2C_Buffer_Size, 0);
        msg_to_send = 0;
    }
}
// Timer 2 interrupt handler
// Used to record when ADC reads happen in time
void timer2_int_handler()
{
	unsigned char val[1];
	ToMainHigh_sendmsg(1, MSGT_TIMER2, (void *) val);
}
Exemple #12
0
void i2c_master_int_handler() {


    if(!(ic_ptr->status == I2C_IDLE)) {

        switch(ic_ptr->status) {
        case I2C_WRITE_ADDR:
        {
            if(ic_ptr->slave_addr % 2) { // even 0 odd 1
                // read
                ic_ptr->status = I2C_RCV_DATA;
            } else {
                // write
                ic_ptr->status = I2C_WRITE_DATA;
            }
            ic_ptr->bufind = 0;
            SSPBUF = ic_ptr->slave_addr;

            break;
        }
        case I2C_WRITE_DATA:
        {
            if(!SSPCON2bits.ACKSTAT) {
                SSPBUF = ic_ptr->outbuffer[ic_ptr->outbufind];

                if(ic_ptr->outbuflen > ic_ptr->outbufind+1) {
                    ic_ptr->outbufind++; // next data point
                    ic_ptr->status = I2C_WRITE_DATA;
                } else {
                    // actually just receive
                    ic_ptr->status = I2C_REP_START;
                }
            } else {
                // keep trying if we get a NACK
                SSPCON2bits.RSEN = 1;
                ic_ptr->status = I2C_WRITE_ADDR;
            }
            break;
        }
        case I2C_RCV_DATA:
        {
            if(!SSPCON2bits.ACKSTAT) {
                SSPCON2bits.RCEN = 1; // enable receive
                ic_ptr->status = I2C_ACK;
            } else {
                // if we get a NACK send a msg
                if(ic_ptr->buffer[4] == 0x78)
                    LATBbits.LATB2 = 1;
                ToMainHigh_sendmsg(0, MSGT_I2C_MASTER_RECV_FAILED, ic_ptr->buffer);
                LATBbits.LATB2 = 0;
                ic_ptr->buflen = 0; // we don't want any data if it fails
                ic_ptr->status = I2C_IDLE;
            }
            break;
        }
        case I2C_ACK:
        {
            LATBbits.LATB1 = 1;
            LATBbits.LATB1 = 0;
            if(ic_ptr->bufind < ic_ptr->buflen) {
                ic_ptr->buffer[ic_ptr->bufind] = SSPBUF;
                ic_ptr->bufind++;
                ic_ptr->status = I2C_RCV_DATA;

            }
            if(ic_ptr->bufind == ic_ptr->buflen) { // no more data
                ic_ptr->status = I2C_END_WRITE;

                // send the buffer to main
                ToMainHigh_sendmsg(ic_ptr->buflen, MSGT_I2C_MASTER_RECV_COMPLETE, ic_ptr->buffer);

                // NACK
                SSPCON2bits.ACKDT = 1;
                SSPCON2bits.ACKEN = 1;
            } else {
                // ACK
                SSPCON2bits.ACKDT = 0;
                SSPCON2bits.ACKEN = 1;
            }
            break;
        }
        // actually just receive
        case I2C_REP_START:
        {
            ic_ptr->status = I2C_IDLE;
            i2c_master_recv(ic_ptr->buflen);
            break;
        }
        case I2C_END_WRITE:
        {

            SSPCON2bits.PEN = 1; // say stop

            ic_ptr->status = I2C_IDLE;
            break;
        }
        }
    }

}
Exemple #13
0
void uart_recv_int_handler() {

    // Write a byte (one character) to the usart transmit buffer.
    // If 9-bit mode is enabled, the 9th bit is written from the field TX_NINE,
    // found in a union of type USART

#ifdef __USE18F26J50
    if (DataRdy1USART()) {
        uc_ptr->Rx_buffer[uc_ptr->Rx_buflen] = Read1USART();
#else
#ifdef __USE18F46J50
    if (DataRdy1USART()) {
        char data = Read1USART();
#else
    if (DataRdyUSART()) {
        char data = ReadUSART();
#endif
#endif

        switch (msgtype_uart) {
            case MSGTYPE:
                uc_ptr->Rx_buffer[0] = data;
                uc_ptr->Rx_buflen++;
                msgtype_uart = LENGTH;
                break;

            case LENGTH:
                if (uc_ptr->Rx_buflen == 1) {
                    uc_ptr->Rx_buffer[uc_ptr->Rx_buflen] = data;
                    uc_ptr->Rx_buflen++;
                    msgtype_uart = MESSAGE;
                } else {
                    uc_ptr->Rx_buflen = 0;
                    msgtype_uart = MSGTYPE;
                }
                break;

            case MESSAGE:
                if (uc_ptr->Rx_buflen > uc_ptr->Rx_buffer[1]) {
                    uc_ptr->Rx_buffer[uc_ptr->Rx_buflen] = data;
                    uc_ptr->Rx_buflen++;
                    msgtype_uart = CHECKSUM;
                } else {
                    uc_ptr->Rx_buffer[uc_ptr->Rx_buflen] = data;
                    uc_ptr->Rx_buflen++;
                    msgtype_uart = MESSAGE;
                }
                break;

            case CHECKSUM:
                if (uc_ptr->Rx_buflen > uc_ptr->Rx_buffer[1]) {
                    uc_ptr->Rx_buffer[uc_ptr->Rx_buflen] = data;
                    uc_ptr->Rx_buflen++;
                    unsigned char checkSum = 0;
                    unsigned char bufLength = uc_ptr->Rx_buffer[1];

                    // Check for correct checksum.
                    int i = 0;
                    for (; i < uc_ptr->Rx_buffer[1]; i++) {
                        checkSum ^= uc_ptr->Rx_buffer[i + 2];
                    }

                    if (uc_ptr->Rx_buflen != uc_ptr->Rx_buffer[1] + 3) {
                        // Message has been scrambled.
                        uc_ptr->Rx_buffer[0] == COMMAND_NACK;
                    }

                    if (checkSum != uc_ptr->Rx_buffer[uc_ptr->Rx_buflen - 1] || uc_ptr->Rx_buffer[0] == COMMAND_NACK) {
                        // Send previous message again.
                        ToMainHigh_sendmsg(uc_ptr->Tx_buflen, MSGT_UART_SEND, (void *) uc_ptr->Tx_buffer);
                    } else if (uc_ptr->Rx_buffer[0] != COMMAND_ACK) {
                        // Send sensor or motor encoder data to the ARM.
                        ToMainHigh_sendmsg(uc_ptr->Rx_buflen, MSGT_UART_RCV, (void *) uc_ptr->Rx_buffer);
                        // Return an ACK to the Master.
                        ToMainLow_sendmsg(CMD_ACKLEN, MSGT_UART_SEND, (void *) uc_ptr->cmd_ack_buf);
                    } else if (uc_ptr->Rx_buffer[0] == COMMAND_ACK) {
                        // Allow ARM to send a new motor command.
                        motorCommandSent = 1;
                    }
                }
                msgtype_uart = MSGTYPE;
                uc_ptr->Rx_buflen = 0;
                break;

            default:
                break;
        }
    }

#ifdef __USE18F26J50
    if (USART1_Status.OVERRUN_ERROR == 1) {
#else
#ifdef __USE18F46J50
    if (USART1_Status.OVERRUN_ERROR == 1) {
#else
    if (USART_Status.OVERRUN_ERROR == 1) {
#endif
#endif
        // we've overrun the USART and must reset
        // send an error message for this
        RCSTAbits.CREN = 0;
        RCSTAbits.CREN = 1;
        ToMainLow_sendmsg(0, MSGT_OVERRUN, (void *) 0);
    }
}

void uart_send_int_handler() {

    if (uc_ptr->Tx_buflen == uc_ptr->msg_length) {
        PIE1bits.TX1IE = 0; // Clear TXIE to end write.
        uc_ptr->Tx_buflen = 0;
    } else {
        Write1USART(uc_ptr->Tx_buffer[uc_ptr->Tx_buflen++]);
    }
}

void init_uart_recv(uart_comm * uc) {
    uc_ptr = uc;
    uc_ptr->Tx_buflen = 0;
    uc_ptr->Rx_buflen = 0;
    uc_ptr->msg_length = 0;

    // Intialize CMD ACK response.
    uc_ptr->cmd_ack_buf[0] = 0x10;
    uc_ptr->cmd_ack_buf[1] = 0x01;
    uc_ptr->cmd_ack_buf[2] = 0x02;
    uc_ptr->cmd_ack_buf[3] = 0x02;
}

void uart_retrieve_buffer(int length, unsigned char* msgbuffer) {

    int i = 0;
    uc_ptr->Tx_buflen = 0;
    uc_ptr->msg_length = length;

    for (; i < length; i++) {
        uc_ptr->Tx_buffer[i] = msgbuffer[i];
    }
    // Set UART TXF interrupt flag
    PIE1bits.TX1IE = 0x1;
}
Exemple #14
0
void i2c_master_handler() {
    unsigned char i2c_data;
    unsigned char data_read = 0;
    unsigned char error_buf[3];
    char junk;

    // read something if it is there
    if (SSPSTATbits.BF == 1) {
        i2c_data = SSPBUF;
        data_read = 1;
    }
    switch(ic_ptr->status) {
        case I2C_IDLE: {
            ic_ptr->actual = 0;
            break;
        };
        case I2C_MASTER_SEND_ADDR: {
            SSPBUF = ic_ptr->slave_addr & 0xFE;
            ic_ptr->status = I2C_MASTER_SEND;
            break;
        };
        case I2C_MASTER_SEND: {
            if (ic_ptr->outbufind < ic_ptr->outbuflen) {
                SSPBUF = ic_ptr->outbuffer[ic_ptr->outbufind];
                ic_ptr->outbufind++;
            } else {
                // we have nothing left to send
                ToMainHigh_sendmsg(ic_ptr->outbuflen,MSGT_I2C_MASTER_SEND_COMPLETE,(void *) ic_ptr->outbuffer);
                SSPCON2bits.PEN = 1;
                ic_ptr->status = I2C_IDLE;
            }
            break;
        };
        case I2C_MASTER_RECV_ADDR: {
            SSPBUF = ic_ptr->slave_addr | 0x01;
            ic_ptr->status = I2C_MASTER_ADDR_ACK;
            break;
        };
        case I2C_MASTER_ADDR_ACK: {
            SSPCON2bits.RCEN = 1;
            ic_ptr->status = I2C_MASTER_RECV;
            break;
        };
        case I2C_MASTER_RECV: {
            ic_ptr->buffer[ic_ptr->actual] = i2c_data;
            ic_ptr->actual++;
            if(ic_ptr->actual < ic_ptr->expected) {
                ic_ptr->status = I2C_MASTER_ACK;
                SSPCON2bits.ACKDT = 0;
                SSPCON2bits.ACKEN = 1;
            }
            else {
                ToMainHigh_sendmsg(ic_ptr->actual,MSGT_I2C_MASTER_RECV_COMPLETE,(void *) ic_ptr->buffer);
                ic_ptr->status = I2C_STOP;
                SSPCON2bits.ACKDT = 1;
                SSPCON2bits.ACKEN = 1;
            }
            break;
        };
        case I2C_MASTER_ACK: {
            SSPCON2bits.RCEN = 1;
            ic_ptr->status = I2C_MASTER_RECV;
            break;
        };
        case I2C_STOP: {
            ic_ptr->status = I2C_IDLE;
            SSPCON2bits.PEN = 1;
            ic_ptr->actual = 0;
            break;
        };
    }
}
Exemple #15
0
int motor_lthread(int msgtype,int length,unsigned char* msgbuffer)
{

    switch (msgtype)
    {
        case (MSGT_MOTOR_COMMAND):
        {
            char message[2];
            lastMotorCommand = msgbuffer[0];
            switch(msgbuffer[0])
            {
                case (0x01):
                {
                    //Turn Left Fast
                    message[0] = Fast_Backward_LM;
                    message[1] = Fast_Forward_RM;
                    break;

                };
                case (0x02):
                {
                    //Turn Right Fast
                    message[0] = Fast_Backward_LM;
                    message[1] = Fast_Forward_RM;
                    break;
                };
                case (0x03):
                {
                    //Straight Fast
                    message[0] = Fast_Forward_LM;
                    message[1] = Fast_Forward_RM;
                    break;
                };
                case (0x04):
                {
                    //Emergrency Stop
                    message[0] = Stop;
                    message[1] = Stop;
                    break;
                };
                case (0x05):
                {
                    //Turn Left Slow
                    message[0] = Slow_Backward_LM;
                    message[1] = Slow_Forward_RM;
                    break;
                };
                case (0x06):
                {
                    //Turn Right Slow
                    message[0] = Slow_Backward_RM;
                    message[1] = Slow_Forward_LM;
                    break;
                };
                default:
                {
                    //Straight Slow
                    message[0] = Slow_Forward_RM;
                    message[1] = Slow_Forward_LM;
                    break;
                };
            }
            
            ToMainHigh_sendmsg(2,MSGT_UART_SEND,&message );
            break;
        };
        default:
        {
          break;  
        };
        
        
        
        
    }



}
Exemple #16
0
void i2c_master_handler() {
    // Make sure we are not in an idle state, or else we don't know why this
    // interrupt triggered.
    if (ic_ptr->state != I2C_IDLE) {
        switch (ic_ptr->substate) {
            case I2C_SUBSTATE_START_SENT:
            {
                // The Start has completed, send the address and W bit (0)
                SSPBUF = (ic_ptr->slave_addr << 1);

                // Move to the next substate
                ic_ptr->substate = I2C_SUBSTATE_ADDR_W_SENT;

                break;
            } // End case I2C_SUBSTATE_START_SENT

            case I2C_SUBSTATE_ADDR_W_SENT:
            {
                // Sending of the address has completed, check the ACK status
                // and send some data.

#ifndef I2C_MASTER_IGNORE_NACK
                // Check for a NACK (ACKSTAT 0 indicates ACK received)
                if (1 == SSPCON2bits.ACKSTAT) {
                    // NACK probably means there is no slave with that address
                    i2c_master_handle_error();
                } else
#endif
                {
                    unsigned char first_byte;

                    // The first byte differs for reads and writes
                    if (I2C_WRITE == ic_ptr->state) {
                        first_byte = ic_ptr->buffer[ic_ptr->buffer_index];
                    } else if (I2C_READ == ic_ptr->state) {
                        first_byte = ic_ptr->register_byte;
                    }

                    // Send the first byte
                    SSPBUF = first_byte;

                    // Move to the next substate
                    ic_ptr->substate = I2C_SUBSTATE_DATA_SENT;
                }
                break;
            } // End case I2C_SUBSTATE_ADDR_W_SENT

            case I2C_SUBSTATE_DATA_SENT:
            {
                // A data byte has completed, send the next one or finish the
                // write.

#ifndef I2C_MASTER_IGNORE_NACK
                // Check for a NACK (ACKSTAT 0 indicates ACK received)
                if (1 == SSPCON2bits.ACKSTAT) {
                    // NACK probably means there is no slave with that address
                    i2c_master_handle_error();
                } else
#endif
                {
                    // The path differs for reads and writes
                    if (I2C_WRITE == ic_ptr->state) {
                        // Increment the data index
                        ic_ptr->buffer_index++;

                        // Check if there is more data to send
                        if (ic_ptr->buffer_index < ic_ptr->buffer_length) {
                            // Send the next byte
                            SSPBUF = ic_ptr->buffer[ic_ptr->buffer_index];

                            // Stay in the same substate (we just sent data)
                            ic_ptr->substate = I2C_SUBSTATE_DATA_SENT;

                        }// Otherwise there is no more data
                        else {
                            // Assert a Stop condition (the write is complete)
                            SSPCON2bits.PEN = 1;

                            // Move to the next substate
                            ic_ptr->substate = I2C_SUBSTATE_STOP_SENT;
                        }
                    }
                    else if (I2C_READ == ic_ptr->state) {
                        // Assert a Restart condition
                        SSPCON2bits.RSEN = 1;

                        // Move to the next substate
                        ic_ptr->substate = I2C_SUBSTATE_RESTART_SENT;
                    }

                } // End ACK check - else

                break;
            } // End case I2C_SUBSTATE_DATA_SENT

            case I2C_SUBSTATE_ERROR:
                // Both substates indicate a stop has completed
            case I2C_SUBSTATE_STOP_SENT:
            {
                // The Stop has completed, return to idle and send a message to
                // main as appropriate

                // Send a success message to main only if this point was reached
                // through normal operation.
                if (ic_ptr->substate != I2C_SUBSTATE_ERROR) {
                    // Send a success message to main
                    if (I2C_WRITE == ic_ptr->state) {
                        ToMainHigh_sendmsg(0, MSGT_I2C_MASTER_SEND_COMPLETE, NULL);
                    } else if (I2C_READ == ic_ptr->state) {
                        ToMainHigh_sendmsg(ic_ptr->buffer_index, MSGT_I2C_MASTER_RECV_COMPLETE, ic_ptr->buffer);
                    }

                }// Otherwise send the appropriate error message to main
                else {
                    // Send an error message to main
                    if (I2C_WRITE == ic_ptr->state) {
                        ToMainHigh_sendmsg(0, MSGT_I2C_MASTER_SEND_FAILED, NULL);
                    } else if (I2C_READ == ic_ptr->state) {
                        ToMainHigh_sendmsg(0, MSGT_I2C_MASTER_RECV_FAILED, NULL);
                    }
                }

                // Return to idle states
                ic_ptr->state = I2C_IDLE;
                ic_ptr->substate = I2C_SUBSTATE_IDLE;

                break;
            } // End case I2C_SUBSTATE_STOP_SENT

            case I2C_SUBSTATE_RESTART_SENT:
            {
                // The restart has completed, send the address and R bit (1)
                SSPBUF = (ic_ptr->slave_addr << 1) | 0x01;

                // Move to the next substate
                ic_ptr->substate = I2C_SUBSTATE_ADDR_R_SENT;

                break;
            } // End case I2C_SUBSTATE_RESTART_SENT

            case I2C_SUBSTATE_ADDR_R_SENT:
            {
                // Sending of the address has completed, check the ACK status
                // and prepare to receive data.

#ifndef I2C_MASTER_IGNORE_NACK
                // Check for a NACK (ACKSTAT 0 indicates ACK received)
                if (1 == SSPCON2bits.ACKSTAT) {
                    // NACK probably means there is no slave with that address
                    i2c_master_handle_error();
                } else
#endif
                {
                    // Prepare to receive a byte
                    SSPCON2bits.RCEN = 1;

                    // Move to the next substate
                    ic_ptr->substate = I2C_SUBSTATE_WAITING_TO_RECEIVE;
                }

                break;
            } // End cases I2C_SUBSTATE_ADDR_R_SENT and I2C_SUBSTATE_ACK_SENT

            case I2C_SUBSTATE_WAITING_TO_RECEIVE:
            {
                // A byte has been received, ACK or NACK it as appropriate.

                // Save the byte
                ic_ptr->buffer[ic_ptr->buffer_index] = SSPBUF;

                // Increment the index (received byte counter)
                ic_ptr->buffer_index++;

                // Check if all requested bytes have been received
                if (ic_ptr->buffer_index < ic_ptr->buffer_length) {
                    // Prepare to ACK the byte
                    SSPCON2bits.ACKDT = 0;

                    // Move to the next substate
                    ic_ptr->substate = I2C_SUBSTATE_ACK_SENT;

                }// Otherwise no more data is needed from the slave
                else {
                    // Prepare to NACK the byte
                    SSPCON2bits.ACKDT = 1;

                    // Move to the next substate
                    ic_ptr->substate = I2C_SUBSTATE_NACK_SENT;
                }

                // Send the ACK/NACK as configured above
                SSPCON2bits.ACKEN = 1;

                break;
            } // End case I2C_SUBSTATE_WAITING_TO_RECEIVE

            case I2C_SUBSTATE_ACK_SENT:
            {
                // Sending of the ACK has completed, prepare to receive a byte
                SSPCON2bits.RCEN = 1;

                // Move to the next substate
                ic_ptr->substate = I2C_SUBSTATE_WAITING_TO_RECEIVE;

                break;
            } // End case I2C_SUBSTATE_ACK_SENT

            case I2C_SUBSTATE_NACK_SENT:
            {
                // Sending of the NACK has completed, assert a Stop to complete
                // the read.
                SSPCON2bits.PEN = 1;

                // Move to the next substate
                ic_ptr->substate = I2C_SUBSTATE_STOP_SENT;

                break;
            } // End case I2C_SUBSTATE_NACK_SENT

            default:
            {
                i2c_master_handle_error();
                break;
            } // End default case
        }
    } else {
        // The only time we should get an interrupt while in IDLE is if a Stop
        // was asserted after an error.  If that's not what heppened, indicate
        // an error
        if (I2C_SUBSTATE_ERROR != ic_ptr->substate) {
            SET_I2C_ERROR_PIN();
        }

        ic_ptr->state = I2C_IDLE;
        ic_ptr->substate = I2C_SUBSTATE_IDLE;
    }
}
Exemple #17
0
void timer1_int_handler() {
    unsigned int result;

    // read the timer and then send an empty message to main()
    //LATBbits.LATB7 = !LATBbits.LATB7;
    result = ReadTimer1();
    //ToMainLow_sendmsg(0, MSGT_TIMER1, (void *) 0);
    

#if defined (MOTOR_PIC)
    // reset the timer
    WriteTimer1(TIMER1_START);
    ticks_left++;
    
    if ( executingEncode && ticks_left_C > 0)
        ticks_left_C--;
    if ( executingEncodeLong && ticks_left_C_Long > 0)
        ticks_left_C_Long--;

    ticks_left_total++;

    if ( ticks_left_C  <= 1 && ticks_right_C <= 1 && executingEncode ) {
        if ( motor_state == RoverMsgMotorForward)
            RoverForward();
        
        else if ( motor_state == RoverMsgMotorLeft2 || motor_state == RoverMsgMotorRight2 ) {
            motor_encode_lthread(RoverMsgMotorForwardCMDelim+10);
        }
        else
            RoverStop();

         executingEncode = 0;
    }
    else if ( ticks_right_C_Long  <= 1 && ticks_left_C_Long <= 1 && executingEncodeLong ) {
        if ( motor_state == RoverMsgMotorLeft2 ) {
            motor_encode_lthread(RoverMsgMotorRight2);
        }
        else if ( motor_state == RoverMsgMotorRight2 )
        {
            motor_encode_lthread(RoverMsgMotorLeft2);
        }
        else {
         RoverStop();
        }

         motor_state = RoverMsgMotorStop;
         executingEncodeLong = 0;
    }
    
#elif defined(MAIN_PIC)
    if ( !i2c_master_busy() )
        ToMainHigh_sendmsg(10, MSGT_GET_SENSOR_DATA, (void *) 0);
    
    if ( timer1_extender > 100 && tempWallCorrection == 0 ) {
        tempWallCorrection = 1;
    }
    
    timer1_extender++;

    WriteTimer1(0);
#else
    WriteTimer1(0);
#endif

}
Exemple #18
0
void i2c_master_handler() {
    unsigned char i2c_data;
    unsigned char data;
    unsigned char data_read = 0;
    unsigned char data_written = 0;
    unsigned char msg_ready = 0;
    unsigned char msg_to_send = 0;
    unsigned char msg_sent = 0;
    unsigned char overrun_error = 0;
    //    unsigned char error_buf[3] = 0;

    //    if (SSPCON1bits.SSPOV == 1) {
    //        SSPCON1bits.SSPOV = 0;
    //        // we failed to read the buffer in time, so we know we
    //        // can't properly receive this message, just put us in the
    //        // a state where we are looking for a new message
    //        overrun_error = 1;
    //        ic_ptr->error_count++;
    //        ic_ptr->error_code = I2C_ERR_OVERRUN;
    //    }
    // read something if it is there
    if (SSPSTATbits.BF == 1) {
        i2c_data = SSPBUF;
        data_read = 1;
    }

    if (!overrun_error) {
        switch (ic_ptr->status) {
            case I2C_IDLE:
            {
                //IdleI2C();
                break;
            }
            case I2C_MASTER_SEND_ADDR:
            {
                ic_ptr->status = I2C_MASTER_SEND;
                SSPBUF = (ic_ptr->slave_addr | 0x00);
                break;
            }
            case I2C_MASTER_SEND:
            {
                ic_ptr->event_count++;
                // send mode
                if (ic_ptr->outbufind < ic_ptr->outbuflen) {
                    //SSPBUF = ic_ptr->outbuffer[ic_ptr->outbufind];
                    SSPBUF = ic_ptr->outbuffer[ic_ptr->outbufind];
                    if (!SSPCON2bits.ACKSTAT)
                        ic_ptr->outbufind++;
                    // ack not received in transmit mode
                } else {
                    data_written = 1;
                    // we have nothing left to send
                    ic_ptr->status = I2C_IDLE;
                    msg_sent = 1;
                    StopI2C();
                }
                break;
            }
            case I2C_MASTER_RECV_ADDR1:
            {
                ic_ptr->status = I2C_MASTER_RECV_ADDR2;
                data = SSPBUF;
                SSPBUF = (ic_ptr->slave_addr | 0x00);
                break;
            }
            case I2C_MASTER_RECV_ADDR2:
            {
                ic_ptr->status = I2C_STARTED;
                SSPBUF = 0xAA;
                break;
            }
            case I2C_MASTER_RECV_ADDR3:
            {
                ic_ptr->status = I2C_MASTER_RECV;
                data = SSPBUF;
                SSPBUF = ic_ptr->slave_addr | 0x01;
                break;
            }
            case I2C_STARTED:
            {
                ic_ptr->status = I2C_MASTER_RECV_ADDR3;
                IdleI2C();
                SSPCON2bits.RSEN = 1;
                break;
            }
            case I2C_MASTER_DATA_READ:
            {
                //LATB = 0xFF;
                if (data_read) {
                    ic_ptr->buffer[buflen1] = i2c_data;
                    if (buflen1 < (explen1-1)) {
                        ic_ptr->status = I2C_MASTER_RECV;
                        buflen1++;
                        SSPCON2bits.ACKDT = 0;
                        SSPCON2bits.ACKEN = 1;
                    } else {
                        ToMainHigh_sendmsg(explen1, MSGT_I2C_DATA, ic_ptr->buffer);
                        ic_ptr->status = I2C_STOP;
                        SSPCON2bits.ACKDT = 1;
                        SSPCON2bits.ACKEN = 1;
                    }
                }
                break;
            }
            case I2C_MASTER_RECV:
            {
                //                if (SSPCON2bits.ACKSTAT == 1)
                //                {
                //                    ic_ptr->status = I2C_MASTER_RECV_ADDR;
                //                }
                //                else {
                SSPCON2bits.RCEN = 1;
                ic_ptr->status = I2C_MASTER_DATA_READ;
                ic_ptr->event_count++;
                //                }
                // receive mode

                break;
            }
            case I2C_STOP:
            {
                ic_ptr->status = I2C_IDLE;
                SSPCON2bits.PEN = 1;
                break;
            }
        }

    }

}
// this is the interrupt handler for i2c -- it is currently built for slave mode
// -- to add master mode, you should determine (at the top of the interrupt handler)
//    which mode you are in and call the appropriate subroutine.  The existing code
//    below should be moved into its own "i2c_slave_handler()" routine and the new
//    master code should be in a subroutine called "i2c_master_handler()"
void i2c_int_handler()
{
	unsigned char	i2c_data;
	unsigned char	data_read = 0;
	unsigned char	data_written = 0;
	unsigned char	msg_ready = 0;
	unsigned char	msg_to_send = 0;
	unsigned char	overrun_error = 0;
	unsigned char	error_buf[3];

	// clear SSPOV
	if (SSPCON1bits.SSPOV == 1) {
		SSPCON1bits.SSPOV = 0;
		// we failed to read the buffer in time, so we know we
		// can't properly receive this message, just put us in the
		// a state where we are looking for a new message
		ic_ptr->status = I2C_IDLE;
		overrun_error = 1;
		ic_ptr->error_count++;
		ic_ptr->error_code = I2C_ERR_OVERRUN;
	}
	// read something if it is there
	if (SSPSTATbits.BF == 1) {
		i2c_data = SSPBUF;
		data_read = 1;
	}



	if (!overrun_error) {
		switch(ic_ptr->status) {
			case	I2C_IDLE: {
				// ignore anything except a start
				if (SSPSTATbits.S == 1) {
					handle_start(data_read);	
					// if we see a slave read, then we need to handle it here
					if (ic_ptr->status == I2C_SLAVE_SEND) {
						data_read = 0;
						msg_to_send = 1;
					}
				}	
				break;
			}
			case	I2C_STARTED: {
				// in this case, we expect either an address or a stop bit
				if (SSPSTATbits.P == 1) {
					// we need to check to see if we also read an
					// address (a message of length 0)
					ic_ptr->event_count++;
					if (data_read) {
						if (SSPSTATbits.D_A == 0) {
							msg_ready = 1;
						} else {
							ic_ptr->error_count++;
							ic_ptr->error_code = I2C_ERR_NODATA;
						}
					}
					ic_ptr->status = I2C_IDLE;
				} else if (data_read) {
					ic_ptr->event_count++;
					if (SSPSTATbits.D_A == 0) {
						if (SSPSTATbits.R_W == 0) { // slave write
							ic_ptr->status = I2C_RCV_DATA;
						} else { // slave read
							ic_ptr->status = I2C_SLAVE_SEND;
							msg_to_send = 1;
							// don't let the clock stretching bit be let go
							data_read = 0;
						}
					} else {
						ic_ptr->error_count++;
						ic_ptr->status = I2C_IDLE;
						ic_ptr->error_code = I2C_ERR_NODATA;
					}
				}
				break;
			}
			case I2C_SLAVE_SEND: {
				if (ic_ptr->outbufind < ic_ptr->outbuflen) {
					SSPBUF = ic_ptr->outbuffer[ic_ptr->outbufind];
					ic_ptr->outbufind++;
					data_written = 1;
				} else {
					// we have nothing left to send
					ic_ptr->status = I2C_IDLE;
				}
				break;
			}
			case I2C_RCV_DATA: {
				// we expect either data or a stop bit or a (if a restart, an addr)
				 if (SSPSTATbits.P == 1) {
					// we need to check to see if we also read data
					ic_ptr->event_count++;
					if (data_read) {
						if (SSPSTATbits.D_A == 1) {
							ic_ptr->buffer[ic_ptr->buflen] = i2c_data;
							ic_ptr->buflen++;
							msg_ready = 1;
						} else {
							ic_ptr->error_count++;
							ic_ptr->error_code = I2C_ERR_NODATA;
							ic_ptr->status = I2C_IDLE;
						}
					} else {
						msg_ready = 1;
					}
					ic_ptr->status = I2C_IDLE;
				} else if (data_read) {
					ic_ptr->event_count++;
					if (SSPSTATbits.D_A == 1) {
						ic_ptr->buffer[ic_ptr->buflen] = i2c_data;
						ic_ptr->buflen++;
					} else /* a restart */ {
						if (SSPSTATbits.R_W == 1) {
							ic_ptr->status = I2C_SLAVE_SEND;
							msg_ready = 1;
							msg_to_send = 1;
							// don't let the clock stretching bit be let go
							data_read = 0;
						} else { /* bad to recv an address again, we aren't ready */
							ic_ptr->error_count++;
							ic_ptr->error_code = I2C_ERR_NODATA;
							ic_ptr->status = I2C_IDLE;
						}	
					}
				}
				break;
			}
		}
	}

	// release the clock stretching bit (if we should)
	if (data_read || data_written) {
		// release the clock
		if (SSPCON1bits.CKP == 0) {
			SSPCON1bits.CKP = 1;
		}
	}

	// must check if the message is too long, if 
	if ((ic_ptr->buflen > MAXI2CBUF-2) && (!msg_ready)) {
		ic_ptr->status = I2C_IDLE;
		ic_ptr->error_count++;
		ic_ptr->error_code = I2C_ERR_MSGTOOLONG;
	}

	if (msg_ready) {
		ic_ptr->buffer[ic_ptr->buflen] = ic_ptr->event_count;
		ToMainHigh_sendmsg(ic_ptr->buflen+1,MSGT_I2C_DATA,(void *) ic_ptr->buffer);
		ic_ptr->buflen = 0;
	} else if (ic_ptr->error_count >= I2C_ERR_THRESHOLD) {
		error_buf[0] = ic_ptr->error_count;
		error_buf[1] = ic_ptr->error_code;
		error_buf[2] = ic_ptr->event_count;
		ToMainHigh_sendmsg(sizeof(unsigned char)*3,MSGT_I2C_DBG,(void *) error_buf);
		ic_ptr->error_count = 0;
	}
	// This is inside of the I2C interrupt handler fxn.  
	if (msg_to_send) {
		unsigned char MSG[2];
		unsigned char type;
		int t = 0;
		
		if(ic_ptr->buffer[0] = 0xaa)	{						// Check to make sure master sent 0xaa
			int temp;
			int error;
			// Use block_on_To_I2CQueue to see if master is requesting data from an empty queue...if so,
			// send 0xFF.  If not, send the ADC data received from the I2C message queue to the master.
			if(block_on_To_I2Cqueue())	{						// Defined in messages.c
				error = toI2C_recvmsg(2, &type, (void *) MSG);	// receive ADC value from I2CQ
				//LATB = MSG[0];
				start_i2c_slave_reply(2,MSG);		// send ADC value to Master via I2C
			}
			else	{
				MSG[0] = 0xFF;
				MSG[1] = 0xFF;
				start_i2c_slave_reply(2,MSG);
			}
		}
		msg_to_send = 0;
		//ToMainHigh_sendmsg(0,MSGT_I2C_RQST,(void *)ic_ptr->buffer);
	}
}
Exemple #20
0
void i2c_slave_int_handler() {
    unsigned char i2c_data;
    unsigned char data_read = 0;
    unsigned char data_written = 0;
    unsigned char msg_ready = 0;
    unsigned char msg_to_send = 0;
    unsigned char overrun_error = 0;
    unsigned char error_buf[3];

    // clear SSPOV
    if (SSPCON1bits.SSPOV == 1) {
        SSPCON1bits.SSPOV = 0;
        // we failed to read the buffer in time, so we know we
        // can't properly receive this message, just put us in the
        // a state where we are looking for a new message
        ic_ptr->status = I2C_IDLE;
        overrun_error = 1;
        ic_ptr->error_count++;
        ic_ptr->error_code = I2C_ERR_OVERRUN;
    }
    // read something if it is there
    if (SSPSTATbits.BF == 1) {
        i2c_data = SSPBUF;
        data_read = 1;
    }

    if (!overrun_error) {
        switch (ic_ptr->status) {
        case I2C_IDLE:
        {
            // ignore anything except a start
            if (SSPSTATbits.S == 1) {
                handle_start(data_read);
                // if we see a slave read, then we need to handle it here
                if (ic_ptr->status == I2C_SLAVE_SEND) {
                    data_read = 0;
                    msg_to_send = 1;
                }
            }
            break;
        }
        case I2C_STARTED:
        {
            // in this case, we expect either an address or a stop bit
            if (SSPSTATbits.P == 1) {
                // we need to check to see if we also read an
                // address (a message of length 0)
                ic_ptr->event_count++;
                if (data_read) {
                    if (SSPSTATbits.D_A == 0) {
                        msg_ready = 1;
                    } else {
                        ic_ptr->error_count++;
                        ic_ptr->error_code = I2C_ERR_NODATA;
                    }
                }
                ic_ptr->status = I2C_IDLE;
            } else if (data_read) {
                ic_ptr->event_count++;
                if (SSPSTATbits.D_A == 0) {
                    if (SSPSTATbits.R_W == 0) { // slave write
                        ic_ptr->status = I2C_RCV_DATA;
                    } else { // slave read
                        ic_ptr->status = I2C_SLAVE_SEND;
                        msg_to_send = 1;
                        // don't let the clock stretching bit be let go
                        data_read = 0;
                    }
                } else {
                    ic_ptr->error_count++;
                    ic_ptr->status = I2C_IDLE;
                    ic_ptr->error_code = I2C_ERR_NODATA;
                }
            }
            break;
        }
        case I2C_SLAVE_SEND:
        {
            if (ic_ptr->outbufind < ic_ptr->outbuflen) {
                SSPBUF = ic_ptr->outbuffer[ic_ptr->outbufind];
                ic_ptr->outbufind++;
                data_written = 1;
            } else {
                // we have nothing left to send
                ic_ptr->status = I2C_IDLE;
            }
            break;
        }
        case I2C_RCV_DATA:
        {
            // we expect either data or a stop bit or a (if a restart, an addr)
            if (SSPSTATbits.P == 1) {
                // we need to check to see if we also read data
                ic_ptr->event_count++;
                if (data_read) {
                    if (SSPSTATbits.D_A == 1) {
                        ic_ptr->buffer[ic_ptr->buflen] = i2c_data;
                        ic_ptr->buflen++;
                        msg_ready = 1;
                    } else {
                        ic_ptr->error_count++;
                        ic_ptr->error_code = I2C_ERR_NODATA;
                        ic_ptr->status = I2C_IDLE;
                    }
                } else {
                    msg_ready = 1;
                }
                ic_ptr->status = I2C_IDLE;
            } else if (data_read) {
                ic_ptr->event_count++;
                if (SSPSTATbits.D_A == 1) {
                    ic_ptr->buffer[ic_ptr->buflen] = i2c_data;
                    ic_ptr->buflen++;
                } else { /* a restart */
                    if (SSPSTATbits.R_W == 1) {
                        ic_ptr->status = I2C_SLAVE_SEND;
                        msg_ready = 1;
                        msg_to_send = 1;
                        // don't let the clock stretching bit be let go
                        data_read = 0;
                    } else { /* bad to recv an address again, we aren't ready */
                        ic_ptr->error_count++;
                        ic_ptr->error_code = I2C_ERR_NODATA;
                        ic_ptr->status = I2C_IDLE;
                    }
                }
            }
            break;
        }
        }
    }

    // release the clock stretching bit (if we should)
    if (data_read || data_written) {
        // release the clock
        if (SSPCON1bits.CKP == 0) {
            SSPCON1bits.CKP = 1;
        }
    }

    // must check if the message is too long, if
    if ((ic_ptr->buflen > MAXI2CBUF - 2) && (!msg_ready)) {
        ic_ptr->status = I2C_IDLE;
        ic_ptr->error_count++;
        ic_ptr->error_code = I2C_ERR_MSGTOOLONG;
    }

    if (msg_ready) {
        ic_ptr->buffer[ic_ptr->buflen] = ic_ptr->event_count;
        ToMainHigh_sendmsg(ic_ptr->buflen + 1, MSGT_I2C_DATA, (void *) ic_ptr->buffer);
        ic_ptr->buflen = 0;
    } else if (ic_ptr->error_count >= I2C_ERR_THRESHOLD) {
        error_buf[0] = ic_ptr->error_count;
        error_buf[1] = ic_ptr->error_code;
        error_buf[2] = ic_ptr->event_count;
        ToMainHigh_sendmsg(sizeof (unsigned char) *3, MSGT_I2C_DBG, (void *) error_buf);
        ic_ptr->error_count = 0;
    }
    if (msg_to_send) {
        int length = 0;

        // send to the queue to *ask* for the data to be sent out
        //ToMainHigh_sendmsg(0, MSGT_I2C_RQST, (void *) ic_ptr->buffer);
        if(ic_ptr->buffer[0] == 0xAA) {
            length = 5;

            // Creates the message type and bitmask char values
            unsigned char messageType = 0x01, bitmask = 0x17, checksum;

            // This will hold the message that we want the slave to send
            unsigned char message[5];

            // Stores the appropriate values in the message to be sent
            message[0] = messageType;
            message[1] = adcbuffer[1];
            message[2] = adcbuffer[2];
            message[3] = adcbuffer[3];

            // Creates the checksum
            checksum = message[1] + message[2] + message[3];
            message[4] = checksum & bitmask;

            start_i2c_slave_reply(length, message);
            //adcbuffer[0] = 0; // reset count after send
        } else if(ic_ptr->buffer[0] == 0xBA) {
            // motor stuff
            length = 5;

            unsigned char motormsg[5] = {0x03, 0x04, ((0x04) & 0x17), 0x00, 0x00};
            start_i2c_slave_reply(length, motormsg);

            unsigned char motorcomm[2] = {0x9F, 0x1F};
            if(ic_ptr->buffer[1] == 0xFF) {

                uart_trans(2, motorcomm);
            } else if(ic_ptr->buffer[1] == 0x00) {
                motorcomm[0] = 0x00;
                uart_trans(1, motorcomm);
            }

        }
        msg_to_send = 0;
    }
}
Exemple #21
0
void uart_recv_int_handler() {
#ifdef __USE18F26J50
    if (DataRdy1USART()) {
        uc_ptr->buffer[uc_ptr->buflen] = Read1USART();
#else
#ifdef __USE18F46J50
    if (DataRdy1USART()) {
        uc_ptr->buffer[uc_ptr->buflen] = Read1USART();
#else
    if (DataRdyUSART()) {
        buffer_temp[buf_len] = ReadUSART();
#endif
#endif
        uc_ptr->buflen++;
        buf_len++;
        parseUART();

        // check if a message should be sent
    }
#ifdef __USE18F26J50
    if (USART1_Status.OVERRUN_ERROR == 1) {
#else
#ifdef __USE18F46J50
    if (USART1_Status.OVERRUN_ERROR == 1) {
#else
    if (USART_Status.OVERRUN_ERROR == 1) {
#endif
#endif
        // we've overrun the USART and must reset
        // send an error message for this
        RCSTAbits.CREN = 0;
        RCSTAbits.CREN = 1;
        ToMainHigh_sendmsg(0, MSGT_OVERRUN, (void *) 0);

    }
}

void init_uart_recv(uart_comm *uc) {
    uc_ptr = uc;
    uc_ptr->buflen = 0;
    buf_len = 0;
    command_length = 0;
    command_count = 0;
    State = GET_MSGID;
}

void parseUART()
{
    unsigned char x = uc_ptr->buflen;
   // uart_write(1, &x);
    switch(State)
    {
        case(GET_MSGID):
        {
            command_length = buffer_temp[buf_len -1] & 0xF;
            command_length = command_length;
            if(command_length != 0)
            {
                State = GET_COMMAND;
            }
            else
            {
                State = CHECKSUM;
            }
            break;
        }
        case(GET_COMMAND):
        {
            if(command_count+1 < command_length)
            {
                command_count++;
            }
            else
            {
                State = CHECKSUM;
            }
            break;
        }
        case(CHECKSUM):
        {
            ToMainLow_sendmsg(buf_len ,MSGT_PARSE, &buffer_temp[0]);
            uc_ptr->buflen = 0;
            buf_len = 0;
            State = GET_MSGID;
            command_count = 0;
            command_length = 0;
            break;
        }
    }
}


void uart_write(unsigned char length, unsigned char *msg){

    unsigned char i = 0;
    for(i = 0; i < length; i++){

    #ifdef __USE18F26J50
        while(Busy1USART());
        Write1USART(msg[i]);
    #else
    #ifdef __USE18F46J50
        while(Busy1USART());
        Write1USART(msg[i]);
    #else
        while(BusyUSART());
        WriteUSART(msg[i]);
    #endif
    #endif
    }
}