void Device::init(const VkDeviceCreateInfo &info) { VkDevice dev; if (EXPECT(vkCreateDevice(phy_.handle(), &info, NULL, &dev) == VK_SUCCESS)) Handle::init(dev); init_queues(); init_formats(); }
void init_mii_mem() { int i; init_queues(); init_queue(&rx_free_queue, NUM_MII_RX_BUF, 0); init_queue(&tx_free_queue, NUM_MII_TX_BUF, NUM_MII_RX_BUF); init_queue(&filter_queue, 0, 0); init_queue(&internal_queue, 0, 0); init_queue(&ts_queue, 0, 0); for(i=0;i<2;i++) init_queue(&tx_queue[i], 0, 0); return; }
int main(void) { IntMasterDisable(); /* Set up hardware */ hardware_setup(); init_semaphores(); init_queues(); /* Module initialization */ if (spi_init() && uart_init_task() && uart_protocol_init_task() && status_led_task_init() && uart_echo_init() && par_updater_init() && (xTaskCreate(dreh_task, NAME("Dreh"), DEFAULT_STACK, NULL, PRIORITY_LOW, &task_handles[DREH_T])) == pdPASS && (xTaskCreate(lcd_task, NAME("LCD"), DEFAULT_STACK, NULL, PRIORITY_LOW, &task_handles[LCD_T])) == pdPASS && (xTaskCreate(menu_task, NAME("Menu"), LARGE_STACK, NULL, PRIORITY_LOW, &task_handles[MENU_T])) == pdPASS && (xTaskCreate(numpad_task, NAME("Numpad"), DEFAULT_STACK, NULL, PRIORITY_LOW, &task_handles[NUMPAD_T])) == pdPASS && (xTaskCreate(control_task, NAME("Control"), DEFAULT_STACK, NULL, PRIORITY_HIGH, &task_handles[CONTROL_T])) == pdPASS && (xTaskCreate(blink_task, NAME("Blink"), DEFAULT_STACK, NULL, PRIORITY_LOW, &task_handles[BLINK_T])) == pdPASS && uart_to_spi_init() && step_response_init() && itc_init_uartprinter() #ifdef DEBUG && spi_test_init() && runtimestats_init() #endif /* DEBUG */ ) { vTaskStartScheduler(); } while (1) { /* Will only get here if initialization went wrong. */ } return 1; }
int main(int argc, char *argv[]) { L = atol(argv[1]); K = atol(argv[2]); M = atol(argv[3]); if (signal(SIGINT, exit_server) == SIG_ERR) syserr("Error in signal (SIGINT)"); init_queues(); int thr_err; pthread_t thread_id; make_attr_detached(); if (thr_err = pthread_rwlock_init(&rwlock, NULL)) syserr_ext(thr_err, "Error in function pthread_rwlock_init"); Mesg mesg; int bytes_rcvd; while (1) { if ((bytes_rcvd = msgrcv(msg_rcv_id, &mesg, MAX_BUFF, 0, 0)) <= 0) syserr("Error in msgrcv (receiving type(pid))"); mesg.mesg_data[bytes_rcvd] = '\0'; if (mesg.mesg_type == READ_TYPE_KOM) { if ((thr_err = pthread_create(&thread_id, &attr, serve_committee, &mesg.mesg_data)) != 0) syserr_ext(thr_err, "Error in pthread_create (for serve_committee)"); } else { if ((thr_err = pthread_create(&thread_id, &attr, serve_report, &mesg.mesg_data)) != 0) syserr_ext(thr_err, "Error in pthread_create (for serve_report)"); } } exit_server(0); }
static int eth_open(struct net_device *dev) { struct port *port = netdev_priv(dev); struct npe *npe = port->npe; struct msg msg; int i, err; if (!npe_running(npe)) { err = npe_load_firmware(npe, npe_name(npe), &dev->dev); if (err) return err; if (npe_recv_message(npe, &msg, "ETH_GET_STATUS")) { printk(KERN_ERR "%s: %s not responding\n", dev->name, npe_name(npe)); return -EIO; } port->firmware[0] = msg.byte4; port->firmware[1] = msg.byte5; port->firmware[2] = msg.byte6; port->firmware[3] = msg.byte7; } memset(&msg, 0, sizeof(msg)); msg.cmd = NPE_VLAN_SETRXQOSENTRY; msg.eth_id = port->id; msg.byte5 = port->plat->rxq | 0x80; msg.byte7 = port->plat->rxq << 4; for (i = 0; i < 8; i++) { msg.byte3 = i; if (npe_send_recv_message(port->npe, &msg, "ETH_SET_RXQ")) return -EIO; } msg.cmd = NPE_EDB_SETPORTADDRESS; msg.eth_id = PHYSICAL_ID(port->id); msg.byte2 = dev->dev_addr[0]; msg.byte3 = dev->dev_addr[1]; msg.byte4 = dev->dev_addr[2]; msg.byte5 = dev->dev_addr[3]; msg.byte6 = dev->dev_addr[4]; msg.byte7 = dev->dev_addr[5]; if (npe_send_recv_message(port->npe, &msg, "ETH_SET_MAC")) return -EIO; memset(&msg, 0, sizeof(msg)); msg.cmd = NPE_FW_SETFIREWALLMODE; msg.eth_id = port->id; if (npe_send_recv_message(port->npe, &msg, "ETH_SET_FIREWALL_MODE")) return -EIO; if ((err = request_queues(port)) != 0) return err; if ((err = init_queues(port)) != 0) { destroy_queues(port); release_queues(port); return err; } port->speed = 0; /* force "link up" message */ phy_start(port->phydev); for (i = 0; i < ETH_ALEN; i++) __raw_writel(dev->dev_addr[i], &port->regs->hw_addr[i]); __raw_writel(0x08, &port->regs->random_seed); __raw_writel(0x12, &port->regs->partial_empty_threshold); __raw_writel(0x30, &port->regs->partial_full_threshold); __raw_writel(0x08, &port->regs->tx_start_bytes); __raw_writel(0x15, &port->regs->tx_deferral); __raw_writel(0x08, &port->regs->tx_2part_deferral[0]); __raw_writel(0x07, &port->regs->tx_2part_deferral[1]); __raw_writel(0x80, &port->regs->slot_time); __raw_writel(0x01, &port->regs->int_clock_threshold); /* Populate queues with buffers, no failure after this point */ for (i = 0; i < TX_DESCS; i++) queue_put_desc(port->plat->txreadyq, tx_desc_phys(port, i), tx_desc_ptr(port, i)); for (i = 0; i < RX_DESCS; i++) queue_put_desc(RXFREE_QUEUE(port->id), rx_desc_phys(port, i), rx_desc_ptr(port, i)); __raw_writel(TX_CNTRL1_RETRIES, &port->regs->tx_control[1]); __raw_writel(DEFAULT_TX_CNTRL0, &port->regs->tx_control[0]); __raw_writel(0, &port->regs->rx_control[1]); __raw_writel(DEFAULT_RX_CNTRL0, &port->regs->rx_control[0]); napi_enable(&port->napi); eth_set_mcast_list(dev); netif_start_queue(dev); qmgr_set_irq(port->plat->rxq, QUEUE_IRQ_SRC_NOT_EMPTY, eth_rx_irq, dev); if (!ports_open) { qmgr_set_irq(TXDONE_QUEUE, QUEUE_IRQ_SRC_NOT_EMPTY, eth_txdone_irq, NULL); qmgr_enable_irq(TXDONE_QUEUE); } ports_open++; /* we may already have RX data, enables IRQ */ napi_schedule(&port->napi); return 0; }
void main(void) { char c; signed char length; unsigned char msgtype; unsigned char last_reg_recvd; uart_comm uc; i2c_comm ic; unsigned char msgbuffer[MSGLEN + 1]; unsigned char i; uart_thread_struct uthread_data; // info for uart_lthread timer1_thread_struct t1thread_data; // info for timer1_lthread timer0_thread_struct t0thread_data; // info for timer0_lthread #ifdef __USE18F2680 OSCCON = 0xFC; // see datasheet // We have enough room below the Max Freq to enable the PLL for this chip OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line #else #ifdef __USE18F45J10 OSCCON = 0x82; // see datasheeet OSCTUNEbits.PLLEN = 1; // Makes the clock exceed the PIC's rated speed if the PLL is on 48 HZ #else #ifdef __USE18F26J50 OSCCON = 0xE0; // see datasheeet OSCTUNEbits.PLLEN = 1; #else #ifdef __USE18F46J50 OSCCON = 0xE0; //see datasheet OSCTUNEbits.PLLEN = 1; #else Something is messed up. The PIC selected is not supported or the preprocessor directives are wrong. #endif #endif #endif #endif // initialize my uart recv handling code init_uart_recv(&uc); // initialize the i2c code init_i2c(&ic); // init the timer1 lthread init_timer1_lthread(&t1thread_data); // initialize message queues before enabling any interrupts init_queues(); #ifndef __USE18F26J50 // set direction for PORTB to output PORTB = 0xFF; //TRISB = 0x0; //LATB = 0x0; #endif // how to set up PORTA for input (for the V4 board with the PIC2680) /* PORTA = 0x0; // clear the port LATA = 0x0; // clear the output latch ADCON1 = 0x0F; // turn off the A2D function on these pins // Only for 40-pin version of this chip CMCON = 0x07; // turn the comparator off TRISA = 0x0F; // set RA3-RA0 to inputs */ // initialize Timers OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_EDGE_RISE & T0_SOURCE_EXT & T0_PS_1_1); OpenTimer1(TIMER_INT_ON& T1_SYNC_EXT_OFF & T1_8BIT_RW & T1_SOURCE_EXT & T1_OSC1EN_OFF & T1_PS_1_1); //OpenTimer2(TIMER_INT_ON & T2_PS_1_16) #ifdef __USE18F26J50 // MTJ added second argument for OpenTimer1() OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0); #else #ifdef __USE18F46J50 // OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0); #else //OpenTimer1(TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF); #endif #endif // Decide on the priority of the enabled peripheral interrupts // 0 is low, 1 is high // Timer1 interrupt IPR1bits.TMR1IP = 0; // USART RX interrupt IPR1bits.RCIP = 0; // I2C interrupt IPR1bits.SSPIP = 1; // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D) #if 1 // Note that the temperature sensor Address bits (A0, A1, A2) are also the // least significant bits of LATB -- take care when changing them // They *are* changed in the timer interrupt handlers if those timers are // enabled. They are just there to make the lights blink and can be // disabled. i2c_configure_slave(0x9E); #else // If I want to test the temperature sensor from the ARM, I just make // sure this PIC does not have the same address and configure the // temperature sensor address bits and then just stay in an infinite loop i2c_configure_slave(0x9A); #ifdef __USE18F2680 LATBbits.LATB1 = 1; LATBbits.LATB0 = 1; LATBbits.LATB2 = 1; #endif for (;;); #endif // must specifically enable the I2C interrupts PIE1bits.SSPIE = 1; // configure the hardware USART device #ifdef __USE18F26J50 Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); #else #ifdef __USE18F46J50 Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); #else OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x26); //Low & 0x26 for 48Mhz //High & 0x26 #endif #endif // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); /* Junk to force an I2C interrupt in the simulator (if you wanted to) PIR1bits.SSPIF = 1; _asm goto 0x08 _endasm; */ // printf() is available, but is not advisable. It goes to the UART pin // on the PIC and then you must hook something up to that to view it. // It is also slow and is blocking, so it will perturb your code's operation // Here is how it looks: printf("Hello\r\n"); // loop forever // This loop is responsible for "handing off" messages to the subroutines // that should get them. Although the subroutines are not threads, but // they can be equated with the tasks in your task diagram if you // structure them properly. TRISCbits.RC0 = 1; while (1) { // Call a routine that blocks until either on the incoming // messages queues has a message (this may put the processor into // an idle mode) block_on_To_msgqueues(); // At this point, one or both of the queues has a message. It // makes sense to check the high-priority messages first -- in fact, // you may only want to check the low-priority messages when there // is not a high priority message. That is a design decision and // I haven't done it here. length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // This case be handled by your code. } } else { switch (msgtype) { case MSGT_TIMER0: { timer0_lthread(&t0thread_data, msgtype, length, msgbuffer); break; }; case MSGT_I2C_DATA: { break; }; case MSGT_I2C_DBG: { // Here is where you could handle debugging, if you wanted // keep track of the first byte received for later use (if desired) last_reg_recvd = msgbuffer[0]; break; }; case MSGT_I2C_RQST: { // Generally, this is *NOT* how I recommend you handle an I2C slave request // I recommend that you handle it completely inside the i2c interrupt handler // by reading the data from a queue (i.e., you would not send a message, as is done // now, from the i2c interrupt handler to main to ask for data). // // The last byte received is the "register" that is trying to be read // The response is dependent on the register. start_i2c_slave_reply(length, msgbuffer); break; }; case MSGT_MOTOR_COMMAND: { motor_lthread(msgtype,length,msgbuffer); break; }; case MSGT_MOTOR_STOP: { motor_lthread(msgtype,length,msgbuffer); break; }; case MSGT_UART_SEND: { uart_lthread(&uthread_data,msgtype,length,msgbuffer); break; }; default: { // Your code should handle this error break; }; }; } // Check the low priority queue length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // Your code should handle this situation } } else { switch (msgtype) { case MSGT_PARSE: { //parser_lthread(msgtype,length,msgbuffer); break; }; case MSGT_OVERRUN: case MSGT_UART_DATA: { uart_lthread(&uthread_data, msgtype, length, msgbuffer); break; }; default: { // Your code should handle this error break; }; }; } } }
void main (void) { /* Define Variables --------------------------------------------------------------------- */ // I2C/MSG Q variables char c; // Is this used? signed char length; unsigned char msgtype; unsigned char last_reg_recvd; i2c_comm ic; //unsigned char msgbuffer[MSGLEN+1]; unsigned char msgbuffer[12]; unsigned char i; int I2C_buffer[]; int index = 0; int ITR = 0; int I2C_RX_MSG_COUNT = 0; int I2C_RX_MSG_PRECOUNT = 0; int I2C_TX_MSG_COUNT = 1; // Timer variables timer1_thread_struct t1thread_data; // info for timer1_lthread timer0_thread_struct t0thread_data; // info for timer0_lthread int timer_on = 1; int timer2Count0 = 0, timer2Count1 = 0; // UART variables uart_comm uc; //uart_thread_struct uthread_data; // info for uart_lthread // ADC variables int ADCVALUE = 0; int adc_counter = 0; int adc_chan_num = 0; int adcValue = 0; int count = 0; // MIDI variable char notePlayed; /* Initialization ------------------------------------------------------------------------ */ // Clock initialization OSCCON = 0x7C; // 16 MHz // Use for internal oscillator OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line // UART initialization init_uart_recv(&uc); // initialize my uart recv handling code // configure the hardware USART device Open2USART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 31); Open1USART( USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 51); //RCSTA1bits.CREN = 1; //RCSTA1bits.SPEN = 1; //TXSTA1bits.SYNC = 0; //PIE1bits.RC1IE = 1; IPR1bits.RC1IP = 0; // I2C/MSG Q initialization init_i2c(&ic); // initialize the i2c code init_queues(); // initialize message queues before enabling any interrupts i2c_configure_slave(0x9E); // configure the hardware i2c device as a slave // Timer initialization init_timer1_lthread(&t1thread_data); // init the timer1 lthread OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_8); OpenTimer2( TIMER_INT_ON & T2_PS_1_16 /*& T2_8BIT_RW & T2_SOURCE_INT & T2_OSC1EN_OFF & T2_SYNC_EXT_OFF*/); // Turn Off // ADC initialization // set up PORTA for input PORTA = 0x0; // clear the port LATA = 0x0; // clear the output latch TRISA = 0xFF; // set RA3-RA0 to inputs ANSELA = 0xFF; initADC(); // Interrupt initialization // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); // Decide on the priority of the enabled peripheral interrupts, 0 is low 1 is high IPR1bits.TMR1IP = 0; // Timer1 interrupt //IPR1bits.RCIP = 0; // USART RX interrupt IPR1bits.SSP1IP = 1; // I2C interrupt PIE1bits.SSP1IE = 1; // must specifically enable the I2C interrupts IPR1bits.ADIP = 1; // ADC interrupt WE ADDED THIS // set direction for PORTB to output TRISB = 0x0; TRISD = 0xFF; LATB = 0x0; ANSELC = 0x00; /* Hand off messages to subroutines ----------------------------------------------------------- */ // This loop is responsible for "handing off" messages to the subroutines // that should get them. Although the subroutines are not threads, but // they can be equated with the tasks in your task diagram if you // structure them properly. while (1) { // Call a routine that blocks until either on the incoming // messages queues has a message (this may put the processor into // an idle mode block_on_To_msgqueues(); /* High Priority MSGQ ---------------------------------------------------------------------- */ // At this point, one or both of the queues has a message. It // makes sense to check the high-priority messages first -- in fact, // you may only want to check the low-priority messages when there // is not a high priority message. That is a design decision and // I haven't done it here. length = ToMainHigh_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { //printf("Error: Bad high priority receive, code = %x\r\n", length); } } else { switch (msgtype) { case MSGT_ADC: { // Format I2C msg msgbuffer[6] = (timer2Count0 & 0x00FF); msgbuffer[5] = (timer2Count0 & 0xFF00) >> 8; msgbuffer[4] = (timer2Count1 & 0x00FF); msgbuffer[3] = (timer2Count1 & 0xFF00) >> 8; msgbuffer[8] = 0x00; msgbuffer[10] = adc_chan_num; msgbuffer[11] = 0xaa; // ADC MSG opcode // Send I2C msg FromMainHigh_sendmsg(12, msgtype, msgbuffer); // Send ADC msg to FromMainHigh MQ, which I2C // int hdlr later Reads // Increment I2C message count from 1 to 100 if(I2C_TX_MSG_COUNT < 100) { I2C_TX_MSG_COUNT = I2C_TX_MSG_COUNT + 1; } else { I2C_TX_MSG_COUNT = 1; } // Increment the channel number if(adc_chan_num <= 4) adc_chan_num++; else adc_chan_num = 0; // Set ADC channel based off of channel number if(adc_chan_num == 0) SetChanADC(ADC_CH0); else if(adc_chan_num == 1) SetChanADC(ADC_CH1); else if(adc_chan_num == 2) SetChanADC(ADC_CH2); else if(adc_chan_num == 3) SetChanADC(ADC_CH3); else if(adc_chan_num == 4) SetChanADC(ADC_CH4); else SetChanADC(ADC_CH5); }; case MSGT_TIMER0: { timer0_lthread(&t0thread_data,msgtype,length,msgbuffer); break; }; case MSGT_TIMER2: { timer2Count0++; if(timer2Count0 >= 0xFFFF) { timer2Count1++; timer2Count0 = 0; } break; } case MSGT_I2C_DATA: { //this data still needs to be put in a buffer ; if(msgbuffer[0] == 0xaf) { //FromMainLow_sendmsg(5, msgtype, msgbuffer); // The code below checks message 'counts' to see if any I2C messages were dropped //I2C_RX_MSG_COUNT = msgbuffer[4]; FromMainLow_sendmsg(9, msgtype, msgbuffer); TXSTA2bits.TXEN = 1; /* // Send note data to the MIDI device //while(Busy2USART()); putc2USART(msgbuffer[1]); //while(Busy2USART()); Delay1KTCYx(8); putc2USART(msgbuffer[2]); //while(Busy2USART()); Delay1KTCYx(8); putc2USART(msgbuffer[3]); */ if(I2C_RX_MSG_COUNT - I2C_RX_MSG_PRECOUNT == 1) { if(I2C_RX_MSG_PRECOUNT < 99) { I2C_RX_MSG_PRECOUNT++; } else { I2C_RX_MSG_PRECOUNT = 0; } } else { I2C_RX_MSG_PRECOUNT = I2C_RX_MSG_COUNT; } } }; ` case MSGT_I2C_DBG: { //printf("I2C Interrupt received %x: ",msgtype); for (i=0;i<length;i++) { //printf(" %x",msgbuffer[i]); } //printf("\r\n"); // keep track of the first byte received for later use last_reg_recvd = msgbuffer[0]; break; }; case MSGT_I2C_RQST: { //printf("I2C Slave Req\r\n"); // The last byte received is the "register" that is trying to be read // The response is dependent on the register. switch (last_reg_recvd) { case 0xaa: { break; } /* case 0xa8: { length = 1; msgbuffer[0] = 0x3A; break; } case 0xa9: { length = 1; msgbuffer[0] = 0xA3; break; }*/ }; //start_i2c_slave_reply(length,msgbuffer); break; }; default: { //printf("Error: Unexpected msg in queue, type = %x\r\n", msgtype); break; }; }; } /* Low Priority MSGQ ----------------------------------------------------------------------- */ length = ToMainLow_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { } } else { switch (msgtype) { case MSGT_TIMER1: { timer1_lthread(&t1thread_data,msgtype,length,msgbuffer); break; }; case MSGT_OVERRUN: case MSGT_UART_DATA: { LATB = 0xFF; msgbuffer[11] = 0xBB; FromMainHigh_sendmsg(12, msgtype, msgbuffer); break; }; default: { break; }; }; } }
//----------------------------------------------------------------------------- // Main... process command line parameters, and then setup our listening // sockets and event loop. int main(int argc, char **argv) { system_data_t sysdata; ///============================================================================ /// Initialization. ///============================================================================ init_sysdata(&sysdata); init_settings(&sysdata); get_options(sysdata.settings, argc, argv); init_maxconns(&sysdata); init_daemon(&sysdata); init_events(&sysdata); init_logging(&sysdata); logger(sysdata.logging, 1, "System starting up"); init_signals(&sysdata); init_buffers(&sysdata); init_servers(&sysdata); init_stats(&sysdata); init_risp(&sysdata); init_nodes(&sysdata); init_msglist(&sysdata); init_queues(&sysdata); init_controllers(&sysdata); ///============================================================================ /// Main Event Loop. ///============================================================================ // enter the event loop. logger(sysdata.logging, 1, "Starting Event Loop"); assert(sysdata.evbase); event_base_loop(sysdata.evbase, 0); logger(sysdata.logging, 1, "Shutdown preparations complete. Shutting down now."); ///============================================================================ /// Shutdown ///============================================================================ cleanup_events(&sysdata); cleanup_controllers(&sysdata); cleanup_queues(&sysdata); cleanup_msglist(&sysdata); cleanup_nodes(&sysdata); cleanup_risp(&sysdata); cleanup_stats(&sysdata); cleanup_servers(&sysdata); cleanup_buffers(&sysdata); cleanup_signals(&sysdata); logger(sysdata.logging, 1, "Shutdown complete.\n"); cleanup_logging(&sysdata); cleanup_daemon(&sysdata); cleanup_maxconns(&sysdata); cleanup_settings(&sysdata); cleanup_sysdata(&sysdata); // good-bye. return 0; }
void main (void) { unsigned int counter=0,curval=0; char c; signed char length, adlength; unsigned char msgtype; unsigned char last_reg_recvd, action; unsigned char adbuffer[2]; uart_comm uc; i2c_comm ic; unsigned char msgbuffer[MSGLEN+1]; unsigned char i; uart_thread_struct uthread_data; // info for uart_lthread timer1_thread_struct t1thread_data; // info for timer1_lthread timer0_thread_struct t0thread_data; // info for timer0_lthread unsigned char data; TRISB = 0b00000011; TRISA = 0x0; TRISC=0b00010000; MIWICS=1; glcdInit(); OSCCON = 0x6C; // 4 MHz OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line // initialize my uart recv handling code // init_uart_recv(&uc); // initialize the i2c code //s init_i2c(&ic); // init the timer1 lthread init_timer1_lthread(&t1thread_data); // initialize message queues before enabling any interrupts init_queues(); // set direction for PORTB to output // TRISB = 0x0; // LATB = 0x0; // set up PORTA for input /* PORTA = 0x0; // clear the port LATA = 0x0; // clear the output latch ADCON1 = 0x0F; // turn off the A2D function on these pins // Only for 40-pin version of this chip CMCON = 0x07; // turn the comparator off TRISA = 0x0F; // set RA3-RA0 to inputs */ // initialize Timers OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_4); // OpenTimer1( TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0); // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); // Decide on the priority of the enabled peripheral interrupts // 0 is low, 1 is high // Timer1 interrupt IPR1bits.TMR1IP = 0; // USART RX interrupt IPR1bits.RCIP = 0; // I2C interrupt IPR1bits.SSPIP = 1; // configure the hardware i2c device as a slave // i2c_configure_slave(0x8A); // must specifically enable the I2C interrupts PIE1bits.SSPIE = 1; // configure the hardware USART device /*OpenUSART( USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19);*/ while(1) { block_on_To_msgqueues(); // At this point, one or both of the queues has a message. It // makes sense to check the high-priority messages first -- in fact, // you may only want to check the low-priority messages when there // is not a high priority message. That is a design decision and // I haven't done it here. length = ToMainHigh_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { printf("Error: Bad high priority receive, code = %x\r\n", length); } } else { switch (msgtype) { case MSGT_TIMER0: { timer0_lthread(&t0thread_data,msgtype,length,msgbuffer); break; }; case MSGT_I2C_DATA: case MSGT_I2C_DBG: { printf("I2C Interrupt received %x: ",msgtype); for (i=0;i<length;i++) { printf(" %x",msgbuffer[i]); } //LATBbits.LATB0 = !LATBbits.LATB0; LATB = msgbuffer[2]; //LATB = msgtype; //LATB=0x01; //printf("\r\n"); // keep track of the first byte received for later use //last_reg_recvd = msgbuffer[0]; //action=msgbuffer[7]; //msgbuffer[0]=0xff; //msgbuffer[1]=0xff; //msgbuffer[2]=0xff; //msgbuffer[3]=0xff; //start_i2c_slave_reply(4,msgbuffer); break; }; case MSGT_I2C_RQST: { printf("I2C Slave Req\r\n"); length=2; /* if(counter==0) { msgbuffer[0]=0x55; msgbuffer[1]=0x55; counter++; }else { msgbuffer[0]=0x22; msgbuffer[1]=0x22; counter=0; }*/ /* adlength = ADQueue_recvmsg(2,0x55,(void *)&adbuffer); if((adlength==MSGQUEUE_EMPTY) || (adlength==MSGBUFFER_TOOSMALL)) { msgbuffer[0]=0xff; msgbuffer[1]=0xff; //msgbuffer[2]=0xff; } else { msgbuffer[0]=adbuffer[0]; msgbuffer[1]=adbuffer[1]; // msgbuffer[0]=0x22; // msgbuffer[1]=0x22; }*/ // LATB=msgbuffer[0]; //printf("XXX: type: %x ADC: %x MsgB1: %x MsgB2: %x\r\n",msgtype,value,msgbuffer[0],msgbuffer[1]); //break; // } //} start_i2c_slave_reply(length,msgbuffer); break; }; case MSGT_LCD_AREA1:{ DEBUG_LED1=1; DEBUG_LED2=0; DEBUG_LED3=0; }; break; case MSGT_LCD_AREA2:{ DEBUG_LED1=0; DEBUG_LED2=1; DEBUG_LED3=0; }; break; case MSGT_LCD_AREA3:{ DEBUG_LED1=1; DEBUG_LED2=1; DEBUG_LED3=0; }; break; case MSGT_LCD_AREA4:{ DEBUG_LED1=0; DEBUG_LED2=0; DEBUG_LED3=1; }; break; case MSGT_LCD_TOUCH:{ DEBUG_LED1=0; DEBUG_LED2=0; DEBUG_LED3=0; }; break; case MSGT_LCD_NOTOUCH:{ DEBUG_LED1=0; DEBUG_LED2=0; DEBUG_LED3=0; }; break; default: { printf("Error: Unexpected msg in queue, type = %x\r\n", msgtype); break; }; }; } // Check the low priority queue length = ToMainLow_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { printf("Error: Bad low priority receive, code = %x\r\n", length); } } else { switch (msgtype) { case MSGT_TIMER1: { timer1_lthread(&t1thread_data,msgtype,length,msgbuffer); break; }; case MSGT_OVERRUN: case MSGT_UART_DATA: { uart_lthread(&uthread_data,msgtype,length,msgbuffer); break; }; default: { printf("Error: Unexpected msg in queue, type = %x\r\n", msgtype); break; }; }; } /*curval=counter%4; counter++; if(curval==0) { writePixelByte(0xf5,CS1); } else { writePixelByte(0x0,CS2); }*/ /*if(curval==0) { data=0b01010101; printSPIHeader(OLATA, data); } else if(curval==1) { data=0b10101010; printSPIHeader(OLATA, data); } else if(curval==2) { data=0b01010101; printSPIHeader(OLATB, data); } else { data=0b10101010; printSPIHeader(OLATB, data); counter=0; } X_PLUS=1;//touchscreen voltage X_MINUS=1; Y_PLUS=0; //Y_MINUS=1; //LATB=LATB|0xf; readADC2(&adcVal); //detect a touch if(adcVal>0x300) //touch threshold { X_PLUS=1;//touchscreen voltage X_MINUS=0; readADC2(&adcVal); //read a touch Y location if(adcVal <0x0f0) { LATCbits.LATC0=1; LATCbits.LATC1=0; LATCbits.LATC2=0; } else if(adcVal<0x1f0) { LATCbits.LATC0=0; LATCbits.LATC1=1; LATCbits.LATC2=0; } else if(adcVal<0x2f0) { LATCbits.LATC0=1; LATCbits.LATC1=1; LATCbits.LATC2=0; } else { LATCbits.LATC0=0; LATCbits.LATC1=0; LATCbits.LATC2=1; } }else { LATCbits.LATC0=0; LATCbits.LATC1=0; LATCbits.LATC2=0; }*/ } }
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; }; }; } } // }
int init_memshare(char *proc_name, int size, int qsize) { int ctrl_mode = 1; int retvalue = 0, index; print(LOG_INFO, "Init_memshare start for %s with size %d\n", proc_name, size); if (initialized) return 1; /* a source proc is a must */ if (proc_name == NULL) return 2; memset(my_proc, 0, PROC_NAME_SIZE); strncpy(my_proc, proc_name, PROC_NAME_SIZE - 1); /* If I don't set a qsize I'm considered to be a send proc only */ if (size) send_only = 0; if (!send_only) { init_queues(); seize_queue(&queue_index, "memshare", qsize); } /* clear the cache */ init_mem_proc(); /* start off by locking the ctrl lock */ if ((lock_ctrl_sem = create_lock(SEM_CTRL_KEY, 1)) == -1) { print(LOG_ERR, "Unable to create ctrl lock\n"); return 3; } while (lock(lock_ctrl_sem) < 0) ; print(LOG_DEBUG, "Ctrl locked (init) by %s, %d\n\n", proc_name, lock_ctrl_sem); /*print(LOG_ERR, "%d trylock (init) key=%d, sem=%d\n", try_lock1(lock_ctrl_sem), SEM_CTRL_KEY, lock_ctrl_sem); */ /* map up the ctrl area */ if ((shm_ctrl_ptr = get_shm(SHM_CTRL_KEY, CTRL_SIZE, &ctrl_mode)) == 0) { print(LOG_ERR, "Unable to alloc shared mem\n"); while (unlock(lock_ctrl_sem) < 0) ; return 6; } if (get_index_for_proc(my_proc) != -1) { print(LOG_ERR, "Procname %s already exists\n", my_proc); while (unlock(lock_ctrl_sem) < 0) ; return 4; } if (!send_only) { if ((index = get_first_free()) < 0) { while (unlock(lock_ctrl_sem) < 0) ; print(LOG_ERR, "Max num of processes registered\n"); return 4; } print(LOG_DEBUG, "Next free index is %d\n", index); retvalue = seize_index(index, size, my_proc); if (retvalue == -1) { while (unlock(lock_ctrl_sem) < 0) ; return 6; } } else { print(LOG_INFO, "%s is a send only proc\n", my_proc); } print(LOG_DEBUG, "Ctrl unlocked by %s\n\n", proc_name); while (unlock(lock_ctrl_sem) < 0) ; if (!send_only) start_listen_thread(); print(LOG_DEBUG, "Init_memshare done for %s\n", my_proc); initialized = 1; return 0; }
void main(void) { char c; int count = 0; signed char length; unsigned char msgtype; unsigned char last_reg_recvd; uart_comm uc; i2c_comm ic; unsigned char msgbuffer[MSGLEN + 1]; unsigned char i; uart_thread_struct uthread_data; // info for uart_lthread timer1_thread_struct t1thread_data; // info for timer1_lthread timer0_thread_struct t0thread_data; // info for timer0_lthread unsigned char config1 = 0x00, config2 = 0x00, portconfig = 0x00; #ifdef __USE18F2680 OSCCON = 0xFC; // see datasheet // We have enough room below the Max Freq to enable the PLL for this chip OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line #else #ifdef __USE18F45J10 OSCCON = 0x82; // see datasheeet OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on #else #ifdef __USE18F26J50 OSCCON = 0xE0; // see datasheeet OSCTUNEbits.PLLEN = 1; #else #ifdef __USE18F46J50 OSCCON = 0xE0; //see datasheet OSCTUNEbits.PLLEN = 1; #else Something is messed up. The PIC selected is not supported or the preprocessor directives are wrong. #endif #endif #endif #endif // initialize my uart recv handling code init_uart_recv(&uc); // initialize the code init_i2c(&ic); // init the timer1 lthread init_timer1_lthread(&t1thread_data); // initialize message queues before enabling any interrupts init_queues(); #ifndef __USE18F26J50 // // set direction for PORTB to output // TRISB = 0x0; // LATB = 0x0; #endif PORTB = 0xFF; // Setup PORTBs for debug pins. TRISBbits.RB1 = 0; TRISBbits.RB2 = 0; TRISBbits.RB3 = 0; TRISBbits.RB4 = 0; TRISBbits.RB5 = 0; LATBbits.LATB1 = 0; LATBbits.LATB2 = 0; LATBbits.LATB3 = 0; LATBbits.LATB4 = 0; LATBbits.LATB5 = 0; //line sensor PORTD = 0x0; LATD = 0x0; TRISD3 = 0x1; TRISD4 = 0x1; TRISD5 = 0x1; TRISD6 = 0x1; TRISD7 = 0x1; // initialize Timers OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_EXT & T0_PS_1_1); #ifdef __USE18F26J50 // MTJ added second argument for OpenTimer1() OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF, 0x0); #else #ifdef __USE18F46J50 OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF, 0x0); #else OpenTimer1(TIMER_INT_ON & T1_PS_1_1 & T1_16BIT_RW & T1_SOURCE_EXT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF); WriteTimer1(0xFFCF); #endif #endif // Decide on the priority of the enabled peripheral interrupts // 0 is low, 1 is high // Timer1 interrupt IPR1bits.TMR1IP = 0; // USART TX interrupt IPR1bits.TXIP = 0; // I2C interrupt IPR1bits.SSPIP = 1; // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D) #if 1 // Note that the temperature sensor Address bits (A0, A1, A2) are also the // least significant bits of LATB -- take care when changing them // They *are* changed in the timer interrupt handlers if those timers are // enabled. They are just there to make the lights blink and can be // disabled. i2c_configure_slave(0x9E); #else // If I want to test the temperature sensor from the ARM, I just make // sure this PIC does not have the same address and configure the // temperature sensor address bits and then just stay in an infinite loop i2c_configure_slave(0x9A); #ifdef __USE18F2680 LATBbits.LATB1 = 1; LATBbits.LATB0 = 1; LATBbits.LATB2 = 1; #endif for (;;); #endif // must specifically enable the I2C interrupts PIE1bits.SSPIE = 1; PIE1bits.RCIE = 1; // configure the hardware USART device #ifdef __USE18F26J50 Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); #else #ifdef __USE18F46J50 Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); #else // Configuration Details: // Solve for SPBRG = ((48Mhz/19200)/16)-1 = 155 // Calculated Baud Rate = 48MHz / (4*(624 + 1)) = 19200 // Error (19200 - 19200) / 19200 = 0 OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 39); BAUDCONbits.BRG16 = 0; RCSTAbits.SPEN = 1; RCSTAbits.CREN = 1; #endif #endif // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); // loop forever // This loop is responsible for "handing off" messages to the subroutines // that should get them. Although the subroutines are not threads, but // they can be equated with the tasks in your task diagram if you // structure them properly. while (1) { // Call a routine that blocks until either on the incoming // messages queues has a message (this may put the processor into // an idle mode) block_on_To_msgqueues(); // At this point, one or both of the queues has a message. It // makes sense to check the high-priority messages first -- in fact, // you may only want to check the low-priority messages when there // is not a high priority message. That is a design decision and // I haven't done it here. length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // This case be handled by your code. } } else { switch (msgtype) { case MSGT_I2C_DATA: { uart_lthread(&uthread_data, msgtype, length, msgbuffer); break; }; default: { // Your code should handle this error break; }; }; } // Check the low priority queue length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); } }
// This program // (1) prints to the UART and it reads from the UART // (2) it "prints" what it reads from the UART to portb (where LEDs are connected) // (3) it uses two timers to interrupt at different rates and drive 2 LEDs (on portb) void main (void) { char c; int adcVal; signed char length; unsigned char msgtype; unsigned char last_reg_recvd, action; uart_comm uc; i2c_comm ic; unsigned char msgbuffer[MSGLEN+1]; unsigned char i; uart_thread_struct uthread_data; // info for uart_lthread timer1_thread_struct t1thread_data; // info for timer1_lthread timer0_thread_struct t0thread_data; // info for timer0_lthread initADC(); // set to run really, really fast... OSCCON = 0x6C; // 4 MHz OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line // initialize my uart recv handling code init_uart_recv(&uc); // initialize the i2c code init_i2c(&ic); // init the timer1 lthread init_timer1_lthread(&t1thread_data); // initialize message queues before enabling any interrupts init_queues(); // set direction for PORTB to output TRISB = 0x0; LATB = 0x0; // set up PORTA for input /* PORTA = 0x0; // clear the port LATA = 0x0; // clear the output latch ADCON1 = 0x0F; // turn off the A2D function on these pins // Only for 40-pin version of this chip CMCON = 0x07; // turn the comparator off TRISA = 0x0F; // set RA3-RA0 to inputs */ // initialize Timers OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_128); OpenTimer1( TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF); // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); // Decide on the priority of the enabled peripheral interrupts // 0 is low, 1 is high // Timer1 interrupt IPR1bits.TMR1IP = 0; // USART RX interrupt IPR1bits.RCIP = 0; // I2C interrupt IPR1bits.SSPIP = 1; // configure the hardware i2c device as a slave i2c_configure_slave(0x8A); // must specifically enable the I2C interrupts PIE1bits.SSPIE = 1; // configure the hardware USART device OpenUSART( USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); /* Junk to force an I2C interrupt in the simulator PIR1bits.SSPIF = 1; _asm goto 0x08 _endasm; */ printf("Hello\r\n"); // loop forever // This loop is responsible for "handing off" messages to the subroutines // that should get them. Although the subroutines are not threads, but // they can be equated with the tasks in your task diagram if you // structure them properly. while (1) { // Call a routine that blocks until either on the incoming // messages queues has a message (this may put the processor into // an idle mode block_on_To_msgqueues(); // At this point, one or both of the queues has a message. It // makes sense to check the high-priority messages first -- in fact, // you may only want to check the low-priority messages when there // is not a high priority message. That is a design decision and // I haven't done it here. length = ToMainHigh_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { printf("Error: Bad high priority receive, code = %x\r\n", length); } } else { switch (msgtype) { case MSGT_TIMER0: { timer0_lthread(&t0thread_data,msgtype,length,msgbuffer); break; }; case MSGT_I2C_DATA: case MSGT_I2C_DBG: { printf("I2C Interrupt received %x: ",msgtype); for (i=0;i<length;i++) { printf(" %x",msgbuffer[i]); } //LATBbits.LATB0 = !LATBbits.LATB0; LATB = msgbuffer[2]; //LATB = msgtype; //LATB=0x01; //printf("\r\n"); // keep track of the first byte received for later use //last_reg_recvd = msgbuffer[0]; //action=msgbuffer[7]; //msgbuffer[0]=0xff; //msgbuffer[1]=0xff; //msgbuffer[2]=0xff; //msgbuffer[3]=0xff; //start_i2c_slave_reply(4,msgbuffer); break; }; case MSGT_I2C_RQST: { printf("I2C Slave Req\r\n"); length=2; msgbuffer[0]=(adcVal>>8)&0xff; msgbuffer[1]=adcVal&0xff; /// msgbuffer[0]=0x55; // msgbuffer[1]=0x55; //printf("XXX: type: %x ADC: %x MsgB1: %x MsgB2: %x\r\n",msgtype,value,msgbuffer[0],msgbuffer[1]); //break; // } //} start_i2c_slave_reply(length,msgbuffer); break; }; default: { printf("Error: Unexpected msg in queue, type = %x\r\n", msgtype); break; }; }; readADC(&adcVal); } // Check the low priority queue length = ToMainLow_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { printf("Error: Bad low priority receive, code = %x\r\n", length); } } else { switch (msgtype) { case MSGT_TIMER1: { timer1_lthread(&t1thread_data,msgtype,length,msgbuffer); break; }; case MSGT_OVERRUN: case MSGT_UART_DATA: { uart_lthread(&uthread_data,msgtype,length,msgbuffer); break; }; default: { printf("Error: Unexpected msg in queue, type = %x\r\n", msgtype); break; }; }; } } }
void main(void) { char c; signed char length; unsigned char msgtype; unsigned char last_reg_recvd; uart_comm uc; i2c_comm ic; unsigned char msgbuffer[MSGLEN + 1]; unsigned char i; uart_thread_struct uthread_data; // info for uart_lthread timer1_thread_struct t1thread_data; // info for timer1_lthread timer0_thread_struct t0thread_data; // info for timer0_lthread #ifdef __USE18F2680 OSCCON = 0xFC; // see datasheet // We have enough room below the Max Freq to enable the PLL for this chip OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line #else #ifdef __USE18F45J10 OSCCON = 0x82; // see datasheeet OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on #else #ifdef __USE18F26J50 OSCCON = 0xE0; // see datasheeet OSCTUNEbits.PLLEN = 1; #else #ifdef __USE18F46J50 OSCCON = 0xE0; //see datasheet OSCTUNEbits.PLLEN = 1; #else Something is messed up. The PIC selected is not supported or the preprocessor directives are wrong. #endif #endif #endif #endif // initialize my uart recv handling code init_uart_recv(&uc); // initialize the i2c code init_i2c(&ic); // init the timer1 lthread init_timer1_lthread(&t1thread_data); // initialize message queues before enabling any interrupts init_queues(); #ifndef __USE18F26J50 // set direction for PORTB to output TRISB = 0xFF; //input LATB = 0x0; PORTA = 0x0; LATA = 0x0; TRISA = 0x0F; #endif // how to set up PORTA for input (for the V4 board with the PIC2680) /* PORTA = 0x0; // clear the port LATA = 0x0; // clear the output latch ADCON1 = 0x0F; // turn off the A2D function on these pins // Only for 40-pin version of this chip CMCON = 0x07; // turn the comparator off TRISA = 0x0F; // set RA3-RA0 to inputs */ // initialize Timers #ifdef MOTORPIC OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_EXT & T0_EDGE_RISE & T0_PS_1_1); #else OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_64); #endif #ifdef __USE18F26J50 // MTJ added second argument for OpenTimer1() OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0); #else #ifdef __USE18F46J50 OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0); #else OpenTimer1(TIMER_INT_ON & T1_8BIT_RW & T1_PS_1_1 & T1_SOURCE_EXT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF); TRISC = 0xFF; // C as input #endif #endif // Decide on the priority of the enabled peripheral interrupts // 0 is low, 1 is high // ADC interrupt IPR1bits.ADIP = 0; PIE1bits.ADIE = 1; // Timer1 interrupt IPR1bits.TMR1IP = 0; // Timer0 interrupt INTCON2bits.TMR0IP = 1; // USART RX interrupt IPR1bits.RCIP = 0; // USART TX interrupt IPR1bits.TXIP = 0; // I2C interrupt IPR1bits.SSPIP = 1; // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D) #if 1 // Note that the temperature sensor Address bits (A0, A1, A2) are also the // least significant bits of LATB -- take care when changing them // They *are* changed in the timer interrupt handlers if those timers are // enabled. They are just there to make the lights blink and can be // disabled. #ifdef I2CMASTER i2c_configure_master(); #else #ifdef SENSORPIC i2c_configure_slave(0x9E); // slave addr 4F #else #ifdef MOTORPIC i2c_configure_slave(0xBE); // slave addr 5F #endif #endif #endif #else // If I want to test the temperature sensor from the ARM, I just make // sure this PIC does not have the same address and configure the // temperature sensor address bits and then just stay in an infinite loop i2c_configure_slave(0x9A); #ifdef __USE18F2680 LATBbits.LATB1 = 1; LATBbits.LATB0 = 1; LATBbits.LATB2 = 1; #endif for (;;); #endif // must specifically enable the I2C interrupts PIE1bits.SSPIE = 1; // configure the hardware USART device #ifdef __USE18F26J50 Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); #else #ifdef __USE18F46J50 Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); #else OpenUSART(USART_TX_INT_ON & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 38); RCSTAbits.SPEN = 1; TRISC = 0xFF; #endif #endif // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); /* Junk to force an I2C interrupt in the simulator (if you wanted to) PIR1bits.SSPIF = 1; _asm goto 0x08 _endasm; */ // printf() is available, but is not advisable. It goes to the UART pin // on the PIC and then you must hook something up to that to view it. // It is also slow and is blocking, so it will perturb your code's operation // Here is how it looks: printf("Hello\r\n"); OpenADC(ADC_FOSC_16 & ADC_LEFT_JUST & ADC_2_TAD, ADC_CH1 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 0b1011); SetChanADC(ADC_CH1); // ADC_CALIB(); // loop forever // This loop is responsible for "handing off" messages to the subroutines // that should get them. Although the subroutines are not threads, but // they can be equated with the tasks in your task diagram if you // structure them properly. unsigned char msg[2] = {0x01, 0x02}; //i2c_master_send(1, 5, msg, 0x9E); // send length, recv length, message and address + r/w bit (0) //i2c_master_recv(); //uart_trans(2, msg); //WriteUSART(0xAA); while (1) { // Call a routine that blocks until either on the incoming // messages queues has a message (this may put the processor into // an idle mode) block_on_To_msgqueues(); // At this point, one or both of the queues has a message. It // makes sense to check the high-priority messages first -- in fact, // you may only want to check the low-priority messages when there // is not a high priority message. That is a design decision and // I haven't done it here. length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // This case be handled by your code. } } else { switch (msgtype) { case MSGT_TIMER0: { timer0_lthread(&t0thread_data, msgtype, length, msgbuffer); break; }; case MSGT_I2C_DATA: case MSGT_I2C_DBG: { // Here is where you could handle debugging, if you wanted // keep track of the first byte received for later use (if desired) last_reg_recvd = msgbuffer[0]; break; }; case MSGT_I2C_MASTER_RECV_COMPLETE: { //msgbuffer[0] = length; uart_trans(length, msgbuffer); //i2c_master_send(1, 5, msg, 0x9E); break; }; case MSGT_I2C_MASTER_RECV_FAILED: { //unsigned char msg2[2] = {0xEE, 0xFF}; //i2c_master_send(1, 5, msg, 0x9E); //LATBbits.LATB2 = 0; break; }; default: { // Your code should handle this error break; }; }; } // Check the low priority queue length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // Your code should handle this situation } } else { switch (msgtype) { case MSGT_TIMER1: { timer1_lthread(&t1thread_data, msgtype, length, msgbuffer); break; }; case MSGT_OVERRUN: case MSGT_UART_DATA: { //uart_trans(2, msgbuffer); if(msgbuffer[0] == 0xBA){ // motor command i2c_master_send(5, 5, msgbuffer, 0xBE); } else if(msgbuffer[0] == 0xAA){ // sensor command i2c_master_send(1, 5, msgbuffer, 0x9E); } LATBbits.LATB2 = 0; //uart_lthread(&uthread_data, msgtype, length, msgbuffer); break; }; default: { // Your code should handle this error break; }; }; } } }
void main(void) { char c; signed char length; unsigned char msgtype; int test_var = 0; unsigned char SENSOR_TYPE_REQUESTED; uart_comm uc; i2c_comm ic; unsigned char msgbuffer[MSGLEN + 1]; unsigned char i; uart_thread_struct uthread_data; // info for uart_lthread timer1_thread_struct t1thread_data; // info for timer1_lthread timer0_thread_struct t0thread_data; // info for timer0_lthread char count = 0; #ifdef __USE18F2680 OSCCON = 0xFC; // see datasheet // We have enough room below the Max Freq to enable the PLL for this chip OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line #else OSCCON = 0x82; // see datasheeet OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on #endif // initialize my uart recv handling code init_uart_recv(&uc); // initialize the i2c code init_i2c(&ic); // init the timer1 lthread init_timer1_lthread(&t1thread_data); // initialize message queues before enabling any interrupts init_queues(); // set direction for PORTB to output TRISB = 0x0; LATB = 0x0; // how to set up PORTA for input (for the V4 board with the PIC2680) /* PORTA = 0x0; // clear the port LATA = 0x0; // clear the output latch ADCON1 = 0x0F; // turn off the A2D function on these pins // Only for 40-pin version of this chip CMCON = 0x07; // turn the comparator off TRISA = 0x0F; // set RA3-RA0 to inputs */ // initialize Timers //OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_128); OpenTimer1(TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF); // WriteTimer1(65086); i2c_configure_slave(0x2A); // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); // Decide on the priority of the enabled peripheral interrupts // 0 is low, 1 is high // Timer1 interrupt IPR1bits.TMR1IP = 0; // USART RX interrupt // IPR1bits.RCIP = 1; // USART TX interrupt // IPR1bits.TXIP = 0; // I2C interrupt IPR1bits.SSPIP = 1; // OpenUSART( USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH & USART_ADDEN_OFF, 38); //38 gives us baud rate of approx 19230 //enable rx interrupts // PIE1bits.RCIE = 1; // PIE1bits.TXIE = 0; //disable send interrupt until we have something in mesage queue //i2c interrupt enable PIE1bits.SSPIE = 1; OpenADC( ADC_FOSC_16 & ADC_RIGHT_JUST & ADC_4_TAD, ADC_CH0 & ADC_INT_ON & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, ADC_0ANA); // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D) #if 1 // Note that the temperature sensor Address bits (A0, A1, A2) are also the // least significant bits of LATB -- take care when changing them // They *are* changed in the timer interrupt handlers if those timers are // enabled. They are just there to make the lights blink and can be // disabled. // i2c_configure_slave(0x9E); #else // If I want to test the temperature sensor from the ARM, I just make // sure this PIC does not have the same address and configure the // temperature sensor address bits and then just stay in an infinite loop i2c_configure_slave(0x9A); LATBbits.LATB1 = 1; LATBbits.LATB0 = 1; LATBbits.LATB2 = 1; for (;;); #endif // must specifically enable the I2C interrupts // PIE1bits.SSPIE = 1; // configure the hardware USART device // OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & // USART_CONT_RX & USART_BRGH_LOW, 0x19); /* Junk to force an I2C interrupt in the simulator (if you wanted to) PIR1bits.SSPIF = 1; _asm goto 0x08 _endasm; */ // printf() is available, but is not advisable. It goes to the UART pin // on the PIC and then you must hook something up to that to view it. // It is also slow and is blocking, so it will perturb your code's operation // Here is how it looks: printf("Hello\r\n"); // loop forever // This loop is responsible for "handing off" messages to the subroutines // that should get them. Although the subroutines are not threads, but // they can be equated with the tasks in your task diagram if you // structure them properly. while (1) { // Call a routine that blocks until either on the incoming // messages queues has a message (this may put the processor into // an idle mode) block_on_To_msgqueues(); // At this point, one or both of the queues has a message. It // makes sense to check the high-priority messages first -- in fact, // you may only want to check the low-priority messages when there // is not a high priority message. That is a design decision and // I haven't done it here. length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // This case be handled by your code. } } else { switch (msgtype) { case MSGT_TIMER0: { timer0_lthread(&t0thread_data, msgtype, length, msgbuffer); break; }; case MSGT_I2C_DATA: case MSGT_I2C_DBG: { // Here is where you could handle debugging, if you wanted // keep track of the first byte received for later use (if desired) SENSOR_TYPE_REQUESTED = msgbuffer[0]; break; }; case MSGT_I2C_RQST: { // Generally, this is *NOT* how I recommend you handle an I2C slave request // I recommend that you handle it completely inside the i2c interrupt handler // by reading the data from a queue (i.e., you would not send a message, as is done // now, from the i2c interrupt handler to main to ask for data). // // The last byte received is the "register" that is trying to be read // The response is dependent on the register. /* switch (SENSOR_TYPE_REQUESTED) { case LASER_DATA_REQUEST: //laser type { break; } case INFRARED_DATA_REQUEST: { length = 4; //place infrared data here msgbuffer[0] = 0x42; msgbuffer[1] = 0x43; msgbuffer[2] = 0x44; msgbuffer[3] = 0x45; break; } default: { length = 1; msgbuffer[0] = 0xFF; break; } }; /* msgbuffer[0] = 0x77; msgbuffer[1] = 0x66; msgbuffer[2] = 0x54*/ length = 6; msgbuffer[0] = 30; msgbuffer[1] = 33+count; msgbuffer[2] = 40; msgbuffer[3] = 43+count; msgbuffer[4] = 44+count; msgbuffer[5] = 45+count; count++; start_i2c_slave_reply(length, msgbuffer); break; }; default: { // Your code should handle this error break; }; }; } // Check the low priority queue length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // Your code should handle this situation } } else { switch (msgtype) { case MSGT_TIMER1: { timer1_lthread(&t1thread_data, msgtype, length, msgbuffer); break; }; case MSGT_OVERRUN: case MSGT_UART_DATA: { uart_lthread(&uthread_data, msgtype, length, msgbuffer); break; }; default: { // Your code should handle this error break; }; }; } } }
void main(void) { TRISA = 0x0; TRISB = 0x0; TRISC = 0x0; PORTA = 0x0; PORTB = 0x0; PORTC = 0x0; LATA = 0x0; LATB = 0x0; LATC = 0x0; signed char length; unsigned char msgtype; uart_comm uc; i2c_comm ic; unsigned char msgbuffer[MSGLEN + 1]; uart_thread_struct uthread_data; // info for uart_lthread timer0_thread_struct t0thread_data; timer1_thread_struct t1thread_data; // info for timer1_lthread encoder_struct encoder_data; sensor_data sensors; #ifdef __USE18F2680 OSCCON = 0xFC; // see datasheet // We have enough room below the Max Freq to enable the PLL for this chip OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line #else OSCCON = 0x82; // see datasheeet OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on #endif #ifdef SENSORPIC i2c2_comm ic2; init_i2c2(&ic2); #endif // initialize everything init_uart_comm(&uc); init_i2c(&ic); init_encoder(&encoder_data); init_timer0_lthread(&t0thread_data); init_timer1_lthread(&t1thread_data); init_uart_lthread(&uthread_data); init_queues(); #ifdef MASTERPIC // Enable and set I2C interrupt to high i2c_configure_master(); IPR1bits.SSPIP = 1; PIE1bits.SSPIE = 1; // initialize Timer0 to go off approximately every 10 ms //OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_1); CloseTimer0(); INTCONbits.TMR0IE = 0; //Enable Timer0 Interrupt // Configure UART OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 9); // 19.2kHz (197910/t - 1 = target) IPR1bits.RCIP = 0; IPR1bits.TXIP = 0; uc.expected = 1; PORTB = 0x0; LATB = 0x0; TRISB = 0x0; #endif //MASTERPIC #ifdef SENSORPIC // Enable and set I2C interrupt to high i2c_configure_slave(SENSORPICADDR); IPR1bits.SSPIP = 1; PIE1bits.SSPIE = 1; i2c2_configure_master(); IPR3bits.SSP2IP = 1; PIE3bits.SSP2IE = 1; // Open ADC on channel 1 ADCON0= 0x01; ADCON1=0x30; ADCON2=0xa1; TRISA=0x0F; PIE1bits.ADIE = 1; //Enabling ADC interrupts IPR1bits.ADIP = 0; //Setting A/D priority // initialize Timer0 to go off approximately every 10 ms OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_128); INTCONbits.TMR0IE = 1; //Enable Timer0 Interrupt INTCON2bits.TMR0IP = 0; //TMR0 set to Low Priority Interrupt #endif //SENSORPIC #ifdef MOTORPIC i2c_configure_slave(MOTORPICADDR); // Enable and set I2C interrupt to high IPR1bits.SSPIP = 1; PIE1bits.SSPIE = 1; // Configure UART OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x9); IPR1bits.RCIP = 0; IPR1bits.TXIP = 0; INTCONbits.TMR0IE = 0; // Disable Timer0 Interrupt PORTB = 0x0; LATB = 0x0; TRISB = 0x0; // Set up RB5 as interrupt TRISBbits.RB5 = 1; INTCON2bits.RBIP = 0; #endif //MOTORPIC #ifdef MASTERPIC //init_communication(MOTORPICADDR); //init_communication(SENSORPICADDR); #endif // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); while (1) { // Spins until a message appears block_on_To_msgqueues(); // Continuously check high priority messages until it is empty while((length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer)) >= 0) { switch (msgtype) { case MSGT_I2C_RQST: { #ifdef SENSORPIC char command = msgbuffer[0]; char length = 0; char buffer[8]; switch(command) { case SHORT_IR1_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x11; } break; case SHORT_IR2_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x22; } break; case MID_IR1_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x33; } break; case MID_IR2_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x44; } break; case COMPASS_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x55; } break; case ULTRASONIC_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x66; } break; default: { length = 2; buffer[0] = 0x0; buffer[1] = 0x0; } break; } if(length > 0) { start_i2c_slave_reply(length,buffer); } #endif #ifdef MOTORPIC unsigned char buffer[8]; unsigned char length = 0; char command = msgbuffer[0]; buffer[0] = command; switch(command) { case MOVE_FORWARD_CMD: { length = 1; motor_move_forward(10); INTCONbits.RBIE = 1; // Temporary } break; case MOVE_BACKWARD_CMD: { length = 1; motor_move_backward(10); } break; case TURN_RIGHT_CMD: { length = 1; motor_turn_right(10); } break; case TURN_LEFT_CMD: { length = 1; motor_turn_left(10); } break; case STOP_CMD: { length = 1; motor_stop(); } break; case DISTANCE_REQ: { INTCONbits.RBIE = 0; // Temporary buffer[1] = encoder_to_distance(); length = 2; } break; default: { buffer[0] = 0x0; length = 1; } break; } if(length > 0) { start_i2c_slave_reply(length,buffer); } #endif } break; case MSGT_I2C_DATA: { } break; case MSGT_I2C_MASTER_SEND_COMPLETE: { #ifdef MASTERPIC /* char command = msgbuffer[0]; switch(command) { case MOVE_FORWARD_CMD: case MOVE_BACKWARD_CMD: case TURN_RIGHT_CMD: case TURN_LEFT_CMD: case STOP_CMD: { i2c_master_recv(1,MOTORPICADDR); } break; case DISTANCE_REQ: { i2c_master_recv(2,MOTORPICADDR); } break; case SHORT_IR1_REQ: case SHORT_IR2_REQ: case MID_IR1_REQ: case MID_IR2_REQ: case COMPASS_REQ: case ULTRASONIC_REQ: { i2c_master_recv(2,SENSORPICADDR); } break; default: { } break; }*/ #endif #ifdef SENSORPIC // Start receiving data from sensor if(t0thread_data.currentState == readCompassState) { i2c2_master_recv(6,COMPASSADDR); } else if(t0thread_data.currentState == readUltrasonicState) { i2c2_master_recv(2,ULTRASONICADDR); } #endif } break; case MSGT_I2C_MASTER_SEND_FAILED: { } break; case MSGT_I2C_MASTER_RECV_COMPLETE: { #ifdef MASTERPIC char buffer[2]; char length = 0; char command = msgbuffer[0]; switch(command) { case MOVE_FORWARD_CMD: case MOVE_BACKWARD_CMD: case TURN_RIGHT_CMD: case TURN_LEFT_CMD: case STOP_CMD: { buffer[0] = command; length = 1; } break; case DISTANCE_REQ: { buffer[0] = command; buffer[1] = msgbuffer[1]; length = 2; } break; case SHORT_IR1_REQ: case SHORT_IR2_REQ: case MID_IR1_REQ: case MID_IR2_REQ: case COMPASS_REQ: case ULTRASONIC_REQ: { buffer[0] = command; buffer[1] = msgbuffer[1]; length = 2; } break; default: { length = 0; } break; } if(length > 0) { start_uart_send(length,buffer); } #endif #ifdef SENSORPIC // Received data from sensor if(t0thread_data.currentState == readCompassState) { sensors.compassData[0] = msgbuffer[0]; sensors.compassData[1] = msgbuffer[1]; sensors.compassData[2] = msgbuffer[2]; sensors.compassData[3] = msgbuffer[3]; sensors.compassData[4] = msgbuffer[4]; sensors.compassData[5] = msgbuffer[5]; } else if(t0thread_data.currentState == readUltrasonicState) { } #endif } break; case MSGT_I2C_MASTER_RECV_FAILED: { } break; case MSGT_I2C_DBG: { } break; default: { } break; } } // Error check if (length != MSGQUEUE_EMPTY) { // Handle Error } // Check the low priority queue if ((length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer)) >= 0) { switch (msgtype) { case MSGT_TIMER0: { timer0_lthread(&t0thread_data, msgtype, length, msgbuffer); } break; case MSGT_TIMER1: timer1_lthread(&t1thread_data, msgtype, length, msgbuffer); break; case ADCSC1_ADCH: ADC_lthread(&ADCthread_data, msgtype, length, msgbuffer,&t0thread_data); break; case MSGT_OVERRUN: case MSGT_UART_DATA: { uart_lthread(&uthread_data, msgtype, length, msgbuffer); } break; case MSGT_UART_SEND_COMPLETE: { } break; default: break; } } // Error check else if (length != MSGQUEUE_EMPTY) { // Handle error } } }
void main(void) { char c; signed char length; unsigned char msgtype; unsigned char last_reg_recvd; i2c_comm ic; unsigned char msgbuffer[MSGLEN + 1]; unsigned char i; uart_thread_struct uthread_data; // info for uart_lthread timer1_thread_struct t1thread_data; // info for timer1_lthread timer0_thread_struct t0thread_data; // info for timer0_lthread t1thread_data.new_move_msg=0; #ifdef __USE18F2680 OSCCON = 0xFC; // see datasheet // We have enough room below the Max Freq to enable the PLL for this chip OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line #else #ifdef __USE18F45J10 OSCCON = 0x82; // see datasheeet OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on #else #ifdef __USE18F26J50 OSCCON = 0xE0; // see datasheeet OSCTUNEbits.PLLEN = 1; #else #ifdef __USE18F46J50 OSCCON = 0xE0; //see datasheet //Alex: //OSCCON : OSCILLATOR CONTROL REGISTER //OSCCON[7] : IDLEN = ( 1 = Device enters Idle mode on SLEEP instruction ) or ( 0 = Device enters Sleep mode on SLEEP instruction ) //OSCCON[6:4] : IRCF; 111 = 8 MHz, 110 = 4 MHz(2), 101 = 2 MHz, 100 = 1 MHz, 011 = 500 kHz, 010 = 250 kHz, 001 = 125 kHz, 000 = 31 kHz //OSCCON[3] : OSTS = Oscillator Start-up Time-out Status bit = ( 1 = Oscillator Start-up Timer time-out has expired; primary oscillator is running ) or ( 0 = Oscillator Start-up Timer time-out is running; primary oscillator is not ready ) //OSCCON[2] : ( Unimplemented: Read as ?1? ) ?????? //OSCCON[0:1] : SCS = System Clock Select bits OSCTUNEbits.PLLEN = 1; #else Something is messed up. The PIC selected is not supported or the preprocessor directives are wrong. #endif #endif #endif #endif // initialize my uart recv handling code //init_uart_recv(&uc); // initialize the i2c code //Alex: //Essentially just sets error and status flags to intial values ( ic is a struct ) init_i2c(&ic); // init the timer1 lthread init_timer1_lthread(&t1thread_data); // initialize message queues before enabling any interrupts init_queues(); #ifndef __USE18F26J50 // set direction for PORTB to output TRISB = 0x0; LATB = 0x0; #endif // how to set up PORTA for input (for the V4 board with the PIC2680) /* PORTA = 0x0; // clear the port LATA = 0x0; // clear the output latch ADCON1 = 0x0F; // turn off the A2D function on these pins // Only for 40-pin version of this chip CMCON = 0x07; // turn the comparator off TRISA = 0x0F; // set RA3-RA0 to inputs */ // initialize Timers OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_128); #ifdef __USE18F26J50 // MTJ added second argument for OpenTimer1() OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0); #else #ifdef __USE18F46J50 OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0); //configure Timer 3 /* TRISAbits.TRISA5 = 1; T3CON = 0x00; T3CONbits.TMR3CS = 0x2; T3CONbits.T3CKPS = 0x0; T3CONbits.RD16 = 0; T3CONbits.T3SYNC = 0; T3CONbits.TMR3ON = 1; RPINR6 = 0x02; */ #else OpenTimer1(TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF); #endif #endif // Decide on the priority of the enabled peripheral interrupts // 0 is low, 1 is high // Timer1 interrupt IPR1bits.TMR1IP = 0; // Timer3 interrupt IPR2bits.TMR3IP = 0; // USART RX interrupt IPR1bits.RCIP = 0; // I2C interrupt IPR1bits.SSPIP = 1; // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D) #if 1 // Note that the temperature sensor Address bits (A0, A1, A2) are also the // least significant bits of LATB -- take care when changing them // They *are* changed in the timer interrupt handlers if those timers are // enabled. They are just there to make the lights blink and can be // disabled. //i2c_configure_slave(0x9E); i2c_configure_master(I2C_DEFAULT_PIC_ADDRESS); #else // If I want to test the temperature sensor from the ARM, I just make // sure this PIC does not have the same address and configure the // temperature sensor address bits and then just stay in an infinite loop i2c_configure_slave(0x9A); for (;;); #endif // must specifically enable the I2C interrupts PIE1bits.SSPIE = 1; /* // configure the hardware USART device #ifdef __USE18F26J50 Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); #else #ifdef __USE18F46J50 Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); #else OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x19); #endif #endif */ // Alex: Set registers for debug output #ifdef DEBUG_MODE debug_configure(); blip(); blip1(); blip2(); blip3(); blip4(); #endif //uart_send_byte( 0x50 ); //uart_send_byte( 0x54 ); // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); /* Junk to force an I2C interrupt in the simulator (if you wanted to) PIR1bits.SSPIF = 1; _asm goto 0x08 _endasm; */ //Alex: Configure UART for transmit and recieve uart_configure(); // Initialize snesor data buffer unsigned char sensor_data[MSGLEN]; sensor_data[0] = MSGID_SENSOR_RESPONSE; for(i=1;i<MSGLEN;i++) { sensor_data[i] = 0x00; } // Initialize motor data buffer unsigned char motor_data[MSGLEN]; motor_data[0] = MSGID_MOTOR_RESPONSE; for(i=1;i<MSGLEN;i++) { motor_data[i] = 0x00; } // printf() is available, but is not advisable. It goes to the UART pin // on the PIC and then you must hook something up to that to view it. // It is also slow and is blocking, so it will perturb your code's operation // Here is how it looks: printf("Hello\r\n"); // loop forever // This loop is responsible for "handing off" messages to the subroutines // that should get them. Although the subroutines are not threads, but // they can be equated with the tasks in your task diagram if you // structure them properly. while (1) { // Call a routine that blocks until either on the incoming // messages queues has a message (this may put the processor into // an idle mode) block_on_To_msgqueues(); // At this point, one or both of the queues has a message. It // makes sense to check the high-priority messages first -- in fact, // you may only want to check the low-priority messages when there // is not a high priority message. That is a design decision and // I haven't done it here. length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // This case be handled by your code. } } else { switch (msgtype) { case MSGT_TIMER0: { timer0_lthread(&t0thread_data, msgtype, length, msgbuffer); break; }; case MSGT_I2C_DATA: { switch(msgbuffer[0]) { case MSGID_SENSOR_RESPONSE: { for(i=2;i<MSGLEN-2;i++) { sensor_data[i] = msgbuffer[i]; } send_uart_message( sensor_data ); break; } case MSGID_MOTOR_RESPONSE: { for(i=2;i<MSGLEN-2;i++) { motor_data[i] = msgbuffer[i]; } //motor_data[3] = 3; send_uart_message( motor_data ); break; } default: { break; } } } case MSGT_I2C_DBG: { // Here is where you could handle debugging, if you wanted // keep track of the first byte received for later use (if desired) last_reg_recvd = msgbuffer[0]; break; }; case MSGT_I2C_RQST: { // Generally, this is *NOT* how I recommend you handle an I2C slave request // I recommend that you handle it completely inside the i2c interrupt handler // by reading the data from a queue (i.e., you would not send a message, as is done // now, from the i2c interrupt handler to main to ask for data). // // The last byte received is the "register" that is trying to be read // The response is dependent on the register. break; }; default: { // Your code should handle this error // Sometimes the best course of action is to do nothing break; }; }; } // Check the low priority queue length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // Your code should handle this situation } } else { unsigned char uart_response[UART_DATA_LENGTH]; int jjj; for(jjj=0;jjj<UART_DATA_LENGTH;jjj++) { uart_response[jjj] = 0; } switch (msgtype) { case MSGT_TIMER1: { timer1_lthread(&t1thread_data, msgtype, length, msgbuffer); break; }; case MSGT_OVERRUN: {} case MSGT_UART_BAD_CHECKSUM: { uart_response[0] = MSGID_UART_BAD_CHECKSUM; //Set Message ID uart_response[1] = msgbuffer[0]; send_uart_message( uart_response ); break; } case MSGT_UART_BAD_COUNTER: { uart_response[0] = MSGID_UART_BAD_COUNTER; //Set Message ID uart_response[1] = msgbuffer[0]; uart_response[2] = msgbuffer[1]; send_uart_message( uart_response ); break; } case MSGT_UART_BAD_START: { uart_response[0] = MSGID_UART_BAD_START; //Set Message ID uart_response[1] = msgbuffer[0]; send_uart_message( uart_response ); break; } case MSGT_UART_BAD_END: { uart_response[0] = MSGID_UART_BAD_END; //Set Message ID uart_response[1] = msgbuffer[0]; send_uart_message( uart_response ); break; } case MSGT_UART_ACK_DATA: { uart_response[0] = MSGID_UART_ACK; //Set Message ID uart_response[1] = msgbuffer[0]; send_uart_message( uart_response ); break; } case MSGT_UART_DATA: { //uart_lthread(&uthread_data, msgtype, length, msgbuffer); switch( msgbuffer[0] ) { case MSGID_STATUS_REQUEST: { //send_uart_message( sensor_data ); break; } case MSGID_SENSOR_REQUEST: { send_uart_message( sensor_data ); break; } case MSGID_MOTOR_REQUEST: { send_uart_message( motor_data ); motor_data[1] = 0; break; } case MSGID_MOVE: { // Copy msgbuffer over for timer 1 to deal with for(i=0;i<UART_DATA_LENGTH;i++) { t1thread_data.move_msg[i] = msgbuffer[i]; } t1thread_data.new_move_msg = 1; break; } default: { break; } } break; }; default: { // Your code should handle this error // Sometimes the best course of action is to do nothing break; }; }; } } }
int main(void) { char c; signed char length; unsigned char msgtype; unsigned char msgbuffer[MSGLEN + 1]; unsigned char i; ANSELA = 0x0; // Set to Digital Function ANSELB = 0x0; ANSELC = 0x0; ANSELD = 0x0; ANSELE = 0x0; UART_DATA uart_data1; UART_DATA uart_data2; TIMER_DATA TIMER1; timer_init(&TIMER1); UART1_Init(&uart_data1); UART2_Init(&uart_data2); TRISAbits.TRISA0 = 0; // Set PIN A as output TRISAbits.TRISA1 = 0; TRISAbits.TRISA2 = 0; // Set PIN A as output TRISAbits.TRISA3 = 0; TRISAbits.TRISA4 = 0; // Set PIN A as output TRISAbits.TRISA5 = 0; TRISAbits.TRISA6 = 0; // Set PIN A as output TRISAbits.TRISA7 = 0; LATAbits.LATA1 = 0; //Set PIN for Stepper motor low // initialize message queues before enabling any interrupts init_queues(); // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); laser_init(); /* Junk to force an I2C interrupt in the simulator (if you wanted to) PIR1bits.SSPIF = 1; _asm goto 0x08 _endasm; */ // printf() is available, but is not advisable. It goes to the UART pin // on the PIC and then you must hook something up to that to view it. // It is also slow and is blocking, so it will perturb your code's operation // Here is how it looks: printf("Hello\r\n"); // loop forever // This loop is responsible for "handing off" messages to the subroutines // that should get them. Although the subroutines are not threads, but // they can be equated with the tasks in your task diagram if you // structure them properly. while (1) { // Call a routine that blocks until either on the incoming // messages queues has a message (this may put the processor into // an idle mode) block_on_To_msgqueues(); // At this point, one or both of the queues has a message. It // makes sense to check the high-priority messages first -- in fact, // you may only want to check the low-priority messages when there // is not a high priority message. That is a design decision and // I haven't done it here. length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // This case be handled by your code. } } else { switch (msgtype) { case MSGT_LASER_READ: { ReadLaser_Message(msgbuffer, length); break; }; case MSGT_WIFLY_RECIEVE: { ReadWIFLY_Message(msgbuffer,length); break; }; default: { // Your code should handle this error break; }; }; } // Check the low priority queue length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer); if (length < 0) { // no message, check the error code to see if it is concern if (length != MSGQUEUE_EMPTY) { // Your code should handle this situation } } else { switch (msgtype) { case MSGT_TIMER0: { Timer_message_handle(); break; }; default: { // Your code should handle this error break; }; }; } } }