void setup() {
	initDebug();
	setupChangeModePin();
	if (isCycleVoltageModeActive()) {
		cycleVoltageMode = true;
		sk720Mode = SK720Mode_off;
		debugln("Cycle mode activated");debug("Switching states every ");debugNum(CYCLE_MODE_DELAY_MS);debugln("ms.");
	} else {
		debugln("Normal mode activated");
		setupLEDPins();
		setuptInitialLedStates();
		setupWatchdogTimer();
		setupPinChangeInterrupts();
	}
	setupFastPWM();
	power_adc_disable();
	power_usi_disable();
}
Beispiel #2
0
void main(void) {
    //char c;
    signed char length;
    unsigned char msgtype;
    unsigned char last_reg_recvd;
    uart_comm uc;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    //    unsigned char to_send_buffer[MAX_I2C_SENSOR_DATA_LEN + HEADER_MEMBERS];
    //    uint8 to_send_len;
    //    int data_points_count = 0;
    //unsigned char i;
    //uart_thread_struct uthread_data; // info for uart_lthread
    //timer1_thread_struct t1thread_data; // info for timer1_lthread
    //timer0_thread_struct t0thread_data; // info for timer0_lthread

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

            // initialize my uart recv handling code

    init_uart_recv(&uc);

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

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

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

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

#endif

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

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

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

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



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

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

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

#endif


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

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

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

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

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

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

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

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

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





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

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

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // Your code should handle this situation
            }
        } else {
            switch (msgtype) {
                case MSGT_AD:
                {
#ifdef SENSOR_PIC
                    //addDataPoints(sensorADid, msgbuffer, length);
#endif
                    break;
                };
                case MSGT_TIMER1:
                {
                    //timer1_lthread(&t1thread_data, msgtype, length, msgbuffer);
                    break;
                };
                    //                case MSGT_OVERRUN:
                    //                    break;
                    //                case MSGT_UART_DATA:
                    //                {
                    //#ifdef PICMAN
                    //                    setRoverDataLP(msgbuffer);
                    //                    handleRoverDataLP();
                    //#elif defined(MASTER_PIC) || defined(ROVER_EMU)
                    //                    setBrainDataLP(msgbuffer);//pass data received and tell will pass over i2c
                    //                    handleMessageLP(UART_COMM, I2C_COMM); //sends the response and then sets up the command handling
                    //#endif
                    //                    break;
                    //                };
                    //                case MSGT_UART_RECV_FAILED:
                    //                {
                    //                    debugNum(1);
                    //                    debugNum(2);
                    //                    debugNum(1);
                    //                    debugNum(2);
                    //                    break;
                    //                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }
    }
//
}
Beispiel #3
0
void uart_recv_wifly_debug_handler(){

#ifdef __USE18F46J50
    if (DataRdy1USART()) {
        unsigned char last = Read1USART();
#else
    if (DataRdyUSART()) {
        unsigned char last = ReadUSART();
#endif
        static unsigned char cur = 0;
        if (last == endmsg[cur]) {
            cur++;
            if(cur >= sizeof endmsg - 1) { //-1 for null terminated
                wifly_setup = 1;
            }
        }
        else{
            cur = 0;
        }
    }
}

void uart_recv_int_handler() {
#ifdef __USE18F26J50
    if (DataRdy1USART()) {
        uc_ptr->buffer[uc_ptr->buflen] = Read1USART();
#else
#ifdef __USE18F46J50
    if (DataRdy1USART()) {
        unsigned char recv = Read1USART();
#else
    if (DataRdyUSART()) {
        unsigned char recv = ReadUSART();

#endif
#endif

        int pos = uc_ptr->buflen++;

        uc_ptr->buffer[pos] = recv;
        //We recieved the last byte of data
        //Check the 5th byte recieved for payload length
        if(pos == PAYLOADLEN_POS){
            payload_length = recv;
        }
        // Get checksum byte
        if(pos == CHECKSUM_POS){
            checksum_recv_value = recv;
        }
        // Count any other byte other than checksum
        else{
            checksum_calc_value += recv;
        }
        // check if a message should be sent
        if (pos == payload_length+HEADER_MEMBERS-1){
            pos++;
            if(checksum_calc_value == checksum_recv_value){
                FromUARTInt_sendmsg(pos, MSGT_UART_DATA, (void *) uc_ptr->buffer);
            }
            else{ //Invalid Checksum
                FromUARTInt_sendmsg(pos, MSGT_UART_RECV_FAILED, (void *) uc_ptr->buffer);
            }
            //Clean up for next packet
            uc_ptr->buflen = 0;
            payload_length = 0;
            checksum_recv_value = 0;
            checksum_calc_value = 0;
#ifdef __USE18F46J50
            //Read1USART();    // clears buffer and returns value to nothing
#else
            //ReadUSART();
#endif
        }
        // portion of the bytes were received or there was a corrupt byte or there was 
        // an overflow transmitted to the buffer
        else if (pos >= MAXUARTBUF)
        {
            FromUARTInt_sendmsg(pos, MSGT_OVERRUN, (void *) uc_ptr->buffer);
            uc_ptr->buflen = 0;
            payload_length = 0;
            checksum_recv_value = 0;
            checksum_calc_value = 0;
        }

    }
#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;
        FromUARTInt_sendmsg(0, MSGT_OVERRUN, (void *) 0);
    }
#ifdef __USE18F46J50
    if (USART1_Status.FRAME_ERROR) {
#else 
    if (USART_Status.FRAME_ERROR) {
#endif
        init_uart_recv(uc_ptr);
    }
}

void init_uart_recv(uart_comm *uc) {
    uc_ptr = uc;
    uc_ptr->status = UART_IDLE;
    uc_ptr->buflen = 0;
    payload_length = 0;
    checksum_recv_value = 0;
    checksum_calc_value = 0;
}

void uart_send_array(char* data, char length) {
#if !defined(SENSOR_PIC) && !defined(MOTOR_PIC)
    if(!wifly_setup) return; //just return
#endif
    if(uc_ptr->status != UART_IDLE){
        if(in_main()){
            debugNum(2);
            if(FromMainHigh_sendmsg(length, MSGT_UART_TX_BUSY, data) == MSGQUEUE_FULL)
                debugNum(4);
        }
        else{
            FromUARTInt_sendmsg(length, MSGT_UART_TX_BUSY, data);
        }
        return;
    }
    uc_ptr->status = UART_TX;
    //TODO: Create logic to prevent you from overriding the current buffer if
    //it has not yet been sent. 
    uint8_t i;
    for(i = 0; i<length; i++) {
        uc_ptr->outBuff[i] = *(data + i);
    }
    uc_ptr->outLength = length;
    uc_ptr->outIndex = 1;
#ifdef __USE18F46J50
    Write1USART(uc_ptr->outBuff[0]);
#else
    WriteUSART(uc_ptr->outBuff[0]);
#endif
    PIR1bits.TXIF = 0;
    PIE1bits.TXIE = 1;
}
//Used to send multiple char. Will get called when uart_send_array is called
//Brian says DONT DELETE! I will find you.
void uart_send_int_handler() {
    if(uc_ptr->outLength > uc_ptr->outIndex){
        uart_send(uc_ptr->outBuff[uc_ptr->outIndex++]);
    }
    else if(uc_ptr->outLength == uc_ptr->outIndex){
        uc_ptr->outIndex++; //still need to increment
    }
    else //uc_ptr->outLength < uc_ptr->outIndex
    {
        // done sending message
        PIE1bits.TXIE = 0;
        PIR1bits.TXIF = 0;
        uc_ptr->status = UART_IDLE;

    }
}

void uart_send(char data){
    //TODO possibly create logic to (without using a while) prevent writing if the buffer is not
    //clear
#ifdef __USE18F46J50
    Write1USART(data);
#else
    WriteUSART(data);
#endif
}