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); } } }
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); } }
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 }
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); } }
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); }
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; } } }
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); }
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; } } } }
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; }
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; }; } }
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; }; } }
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; } }
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 }
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); } }
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; } }
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 } }