//send command int BUS_cmd_tx(unsigned char addr,unsigned char *buff,unsigned short len,unsigned short flags,short bgnd){ unsigned int e; short ret; int i; unsigned char resp[2]; //add standard header length len+=I2C_HDR_LEN; //add NACK flag if requested if(flags&BUS_CMD_FL_NACK){ //request NACK buff[0]|=CMD_TX_NACK; }else{ //clear NACK request buff[0]&=~CMD_TX_NACK; } //calculate CRC buff[len]=crc8(buff,len); //add a byte for the CRC len+=I2C_CRC_LEN; //send command without ack ret=BUS_i2c_tx(addr,buff,len); //check for error if(ret!=RET_SUCCESS){ //return error return ret; } //if transmitting in the background, return if(bgnd){ return RET_SUCCESS; } //wait for transaction to complete //TODO: set a good timeout e=ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,&arcBus_stat.events,BUS_EV_I2C_MASTER,CTL_TIMEOUT_DELAY,2048); //check event for error if(e==BUS_EV_I2C_COMPLETE){ //no error return RET_SUCCESS; }else{ //mask event bits e&=BUS_EV_I2C_MASTER; if(e){ //TODO: give more informative error messages return ERR_UNKNOWN; }else{ //no event happened, so time out return ERR_TIMEOUT; } } }
int takePicTask(char **argv,unsigned short argc) { unsigned short e; int tmp; //get the slot where the picture wil be written tmp=writePic; //Trigger the takepic event and clear pic taken event ctl_events_set_clear(&IMG_events, IMG_EV_TAKEPIC,IMG_EV_PIC_TAKEN); //wait for picture to complete, set a timeout of 15 sec e=ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,&IMG_events,IMG_EV_PIC_TAKEN,CTL_TIMEOUT_DELAY,30*1024); //check if picture was taken if(!(e&IMG_EV_PIC_TAKEN)){ //print error message printf("Error timeout occoured\r\n"); } //set picture slot cmdPic=tmp; return 0; }
void run() { CTL_EVENT_SET_t event_received; // request the battery level periodically msg::payload::enqueue_time_event batt_request; batt_request.message = msg::id::battery_level_request; batt_request.dest = msg::src::aux; batt_request.type = msg::payload::time_event_types::repeating; batt_request.next_time_ms = 0; batt_request.period = 10000; get_central().send_message(msg::src::time_queue, msg::id::enqueue_time_event, sizeof(batt_request), reinterpret_cast<u8*>(&batt_request)); // request the board serial number ( == RF MAC address) get_central().send_message(msg::src::aux, msg::id::serial_number_request); // ensure the files are created before we get into the loop as those operations can take some time #if ENABLE_RAW_LOGGING raw_log_file.get_stream(); #endif #if ENABLEEPHEMERIS_LOGGING eph_mgr.touch_files(); #endif #if ENABLE_ROVER_PROCESSOR rover_pda_link.open(); #endif #if ENABLE_GPS_UART_LOGGING gps_uart_logger.start_logging(); s32 gnss_status = gnss_com_ctrl.init(&gps_uart_logger, &eph_mgr, uart_baud_rates::gps, gnss_dynamic_mode); #else s32 gnss_status = gnss_com_ctrl.init(&get_gps_uart_io(), &eph_mgr, uart_baud_rates::gps, gnss_dynamic_mode); #endif assert(0 == gnss_status); #if ENABLE_ROVER_PROCESSOR msg_handler::proxdet* prox_handlers[2]; prox_handlers[0] = gps_ctrl.get_prox_handler(); prox_handlers[1] = &prox_handler; #endif CTL_EVENT_SET_t listened_events = gps_receive_mask | gps_error_mask | messages_mask #if ENABLE_ROVER_PROCESSOR | rf_receive_mask | rf_error_mask | pda_mask_0 | pda_mask_1 #endif ; bool done = false; while (!done) { if (get_central().system_shutdown_requested()) { // this task can get really busy and has a high priority, which may hamper normal shutdown. detect shutdown and disable the event in order to let lower priority tasks run. listened_events = messages_mask; } // wait for input from the gnss uart (this is setup in the master init_modules function) event_received = ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR, &gnss_receive_event, listened_events, CTL_TIMEOUT_INFINITE, 0); done = observe_all_messages(event_received); #if ENABLE_ROVER_PROCESSOR if (event_received & (rf_receive_mask | gps_receive_mask)) { s32 status = rf_ctrl.rx_rover(gps_ctrl.get_next_base_data(), prox_handlers, 2); while (status > 0) { if (1 == status) { gps_ctrl.process_base_data(); #if ENABLE_RF_DATA_LOGGING raw_base_dump(*gps_ctrl.get_current_base_data(), log_protocol, raw_log_file.get_stream()); #endif } status = rf_ctrl.rx_rover(gps_ctrl.get_next_base_data(), prox_handlers, 2); } } if (event_received & rf_error_mask) { #if ENABLE_GPS_ERROR_LOGGING u8 err_code = get_rf_uart_io().get_last_error(); u32 len = debug::log_to_string(error_buffer, debug::error, "RF uart error 0x%X", err_code); message_dump(error_buffer, len, log_protocol, raw_log_file.get_stream()); #endif } #endif if (event_received & gps_receive_mask) { while (gnss_com_ctrl.gnssrx_getnav(gps_ctrl.get_next_gnss_navdata(), gps_ctrl.get_next_gnss_rawdata())) { #if ENABLE_GPS_DATA_LOGGING gnss_rawdata_dump(*gps_ctrl.get_next_gnss_rawdata(), log_protocol, raw_log_file.get_stream()); if (gps_ctrl.get_next_gnss_navdata()->datavalid) gnss_navdata_dump(*gps_ctrl.get_next_gnss_navdata(), log_protocol, raw_log_file.get_stream()); #endif #if ENABLE_GPS_ERROR_LOGGING s32 gnss_error_code = gnss_com_ctrl.gnssrx_geterror(); if (gnss_error_code) { u32 len = debug::log_to_string(error_buffer, debug::error, "GNSS COM error 0x%X", gnss_error_code); message_dump(error_buffer, len, log_protocol, raw_log_file.get_stream()); } #endif bool new_nav_data; #if ENABLE_BASE_PROCESSOR s32 status = gps_ctrl.process_gnss_data(&bd, &new_nav_data); #endif #if ENABLE_ROVER_PROCESSOR s32 status = gps_ctrl.process_gnss_data(&new_nav_data); rover_pda_link.set_rover_status(status); #endif if (new_nav_data) { get_rt_clock().set_real_time(gps_ctrl.get_current_gnss_navdata().utc, gps_ctrl.get_current_gnss_navdata().tow); #if ENABLE_BASE_PROCESSOR rf_ctrl.tx_base(&bd, fresh_batt_level, status); #endif } #if ENABLE_BASE_PROCESSOR && ENABLE_RF_DATA_LOGGING raw_base_dump(bd, log_protocol, raw_log_file.get_stream()); #endif #if ENABLE_ROVER_PROCESSOR u32 flags = rover::pda_link::raw_data; if (new_nav_data) flags |= rover::pda_link::nav_data; rover_pda_link.update(flags); #endif #if ENABLE_CONSOLE update_debug_status(); #endif if (get_central().system_shutdown_requested()) { // this task can get really busy and has a high priority, which may hamper normal shutdown. detect shutdown and disable the event in order to let lower priority tasks run. listened_events = messages_mask; break; } } } if (event_received & gps_error_mask) { #if ENABLE_GPS_ERROR_LOGGING u8 err_code = get_gps_uart_io().get_last_error(); u32 len = debug::log_to_string(error_buffer, debug::error, "GPS uart error 0x%X", err_code); message_dump(error_buffer, len, log_protocol, raw_log_file.get_stream()); #endif } #if ENABLE_ROVER_PROCESSOR if (event_received & (pda_mask_0 | pda_mask_1)) { rover_pda_link.process_pda_requests(); rover_pda_link.output_console(); } #endif } #if ENABLE_EPHEMERIS_LOGGING eph_mgr.close_files(); // writes to a log file the new ephemeris data we have received #endif #if ENABLE_RAW_LOGGING raw_log_file.close(); #endif #if ENABLE_ROVER_PROCESSOR rover_pda_link.close(); #endif get_int_ctrl().disable_interrupt(lpc3230::interrupt::id::gps_time_pulse); }
int BUS_SPI_txrx(unsigned char addr,unsigned char *tx,unsigned char *rx,unsigned short len){ unsigned char buf[10],*ptr; unsigned int e; short time; int i,resp; unsigned short crc; //reject General call address if(addr==BUS_ADDR_GC){ return ERR_BADD_ADDR; } //calculate CRC crc=crc16(tx,len); //send CRC in Big endian order tx[len]=crc>>8; tx[len+1]=crc; //setup SPI structure arcBus_stat.spi_stat.len=len; arcBus_stat.spi_stat.rx=rx; arcBus_stat.spi_stat.tx=tx; //Setup SPI SPI_slave_setup(); //disable DMA DMA0CTL&=~DMAEN; DMA1CTL&=~DMAEN; //setup DMA for transfer DMACTL0 &=~(DMA0TSEL_15|DMA1TSEL_15); DMACTL0 |= (DMA0TSEL_3|DMA1TSEL_4); //====[DMA channel0 used for receive]==== //check for omitted receive buffer if(rx!=NULL){ // Source DMA address: receive register. DMA0SA = (unsigned short)(&UCA0RXBUF); // Destination DMA address: rx buffer. DMA0DA = (unsigned short)rx; // The size of the block to be transferred DMA0SZ = len+SPI_CRC_LEN; // Configure the DMA transfer, single byte transfer with source increment DMA0CTL =DMADT_0|DMASBDB|DMAEN|DMADSTINCR1|DMADSTINCR0; } //====[DMA channel1 used for transmit]==== // Destination DMA address: the transmit buffer. DMA1DA = (unsigned int)(&UCA0TXBUF); //check for omitted transmit buffer if(tx!=NULL){ // Source DMA address: tx buffer DMA1SA = (unsigned int)tx+1; // The size of the block to be transferred DMA1SZ = len+SPI_CRC_LEN-1; // Configure the DMA transfer, single byte transfer with destination increment //enable interrupt to notify code when transfer is complete DMA1CTL=DMADT_0|DMASBDB|DMASRCINCR1|DMASRCINCR0|DMAEN; //start things off with an initial transfer UCA0TXBUF=*tx; }else{ //need to send something to receive something so setup TX for dummy bytes DMA1SA = (unsigned int)(&UCA0TXBUF); // The size of the block to be transferred DMA1SZ = len+SPI_CRC_LEN-1; // Configure the DMA transfer, single byte transfer with no increment DMA1CTL=DMADT_0|DMASBDB|DMASRCINCR0|DMASRCINCR0|DMAEN; //start things off with an initial transfer UCA0TXBUF=SPI_DUMMY_DATA; } //send SPI setup command ptr=BUS_cmd_init(buf,CMD_SPI_RDY); //send MSB first ptr[0]=len>>8; //then send LSB ptr[1]=len; //send command resp=BUS_cmd_tx(addr,buf,2,BUS_CMD_FL_NACK,SEND_FOREGROUND); //check if sent correctly if(resp!=RET_SUCCESS){ //SPI pins back to GPIO SPI_deactivate(); //Return Error //TODO: better error code here return resp; } //calculate wait time based on packet length time=len/10; if(time<=10){ time=10; } //wait for SPI complete signal from master e=ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,&arcBus_stat.events,BUS_EV_SPI_MASTER,CTL_TIMEOUT_DELAY,time); //disable DMA DMA0CTL&=~DMAEN; DMA1CTL&=~DMAEN; //Check if SPI complete event received if(e&BUS_EV_SPI_COMPLETE){ //assemble CRC crc=rx[arcBus_stat.spi_stat.len+1];//LSB crc|=(((unsigned short)rx[arcBus_stat.spi_stat.len])<<8);//MSB //check CRC if(crc!=crc16(rx,arcBus_stat.spi_stat.len)){ //Bad CRC return ERR_BAD_CRC; } //Success!! return RET_SUCCESS; }else{ //Return error, timeout occurred return ERR_TIMEOUT; } }