/* Main Program */ int main (void) { int j=0; processorInit(); init_VIC(); //necessary 5-17-2006 EDM //initialize the motion control subsystem if( !init_motion_control() ) status_led(MOTION_INIT_ERR); init_status_led(); for(j=0; j<1000000; j++); //short delay here //initialize USB usbSetup(); //if we made it this far, blink to show health status_led(HEALTHY); while (1) /* Loop forever */ { //Allow USB to send information if any needs to be send SendNextBulkIn(BULK_IN_EP); } }
/* Common packets handlers. * Return 1 when packet has been handled, or 0 if the type is not a common one and some * board or application specific code should take care of it. */ static int dtplug_protocol_common_handles(struct dtplug_protocol_handle* handle, struct packet* question) { uint32_t tmp_val_swap = 0; /* These we can always handle */ switch (question->info.type) { case PKT_TYPE_PING: question->info.seq_num |= PACKET_NEEDS_REPLY; /* Make sure the reply will be sent */ dtplug_protocol_send_reply(handle, question, NO_ERROR, 0, NULL); /* A ping needs no aditional data */ dtplug_protocol_release_old_packet(handle); break; case PKT_TYPE_RESET: /* Software reset of the board. No way out. */ NVIC_SystemReset(); break; case PKT_TYPE_SET_TIME: { struct time_spec new_time, time_diff; uint32_t* seconds = (uint32_t*)question->data; uint16_t* msec = (uint16_t*)&(question->data[4]); uint8_t time_buff[6]; if (question->info.seq_num & QUICK_DATA_PACKET) { dtplug_protocol_send_reply(handle, question, ERROR_IN_PKT_STRUCTURE, 0, NULL); break; } if (question->info.data.size != 6) { dtplug_protocol_send_reply(handle, question, ERROR_IN_DATA_VALUES, 0, NULL); break; } new_time.seconds = byte_swap_32(*seconds); new_time.msec = (uint16_t)byte_swap_16(*msec); if (!(question->info.seq_num & PACKET_NEEDS_REPLY)) { set_time(&new_time); } else { set_time_and_get_difference(&new_time, &time_diff); time_to_buff_swapped(time_buff, &time_diff); dtplug_protocol_send_reply(handle, question, NO_ERROR, 6, time_buff); } } dtplug_protocol_release_old_packet(handle); break; case PKT_TYPE_SET_USER_INFO: { uint8_t tmp_data[sizeof(struct user_info)] __attribute__ ((__aligned__(4))) = {}; uint8_t offset = question->data[0]; uint8_t size = question->data[1]; if (question->info.seq_num & QUICK_DATA_PACKET) { dtplug_protocol_send_reply(handle, question, ERROR_IN_PKT_STRUCTURE, 0, NULL); break; } /* Check that amount of data provided is OK and does not go beyond user_info structure end */ if ((question->info.data.size != (size + 2)) || ((offset + size) > sizeof(struct user_info))) { dtplug_protocol_send_reply(handle, question, ERROR_IN_DATA_VALUES, 0, NULL); break; } /* Copy all board data before flash erase */ memcpy(tmp_data, get_user_info(), sizeof(struct user_info)); /* Update information in the copy */ memcpy(&(tmp_data[offset]), &(question->data[2]), size); /* Update the user flash information pages */ if (dtplug_protocol_user_flash_update(handle, question, tmp_data, sizeof(struct user_info)) != 0) { /* Reply got sent, if return value is not 0 */ break; } } /* Software reset of the board. No way out. */ NVIC_SystemReset(); break; case PKT_TYPE_GET_NUM_PACKETS: question->info.seq_num |= PACKET_NEEDS_REPLY; /* Make sure the reply will be sent */ tmp_val_swap = byte_swap_32(handle->packet_count); dtplug_protocol_send_reply(handle, question, NO_ERROR, 4, (uint8_t*)(&tmp_val_swap)); dtplug_protocol_release_old_packet(handle); break; case PKT_TYPE_GET_ERRORS: question->info.seq_num |= PACKET_NEEDS_REPLY; /* Make sure the reply will be sent */ dtplug_protocol_send_reply(handle, question, NO_ERROR, 0, NULL); /* Error handling code will take care of filling the message */ dtplug_protocol_release_old_packet(handle); break; case PKT_TYPE_GET_NUM_ERRORS: question->info.seq_num |= PACKET_NEEDS_REPLY; /* Make sure the reply will be sent */ tmp_val_swap = byte_swap_32(handle->errors_count); dtplug_protocol_send_reply(handle, question, NO_ERROR, 4, (uint8_t*)(&tmp_val_swap)); dtplug_protocol_release_old_packet(handle); break; default: /* We do not handle this type, it must be a board specific one */ return 0; } /* Packet handled */ status_led(green_off); return 1; }
/* 'sum' is used to sum all the received characters, and if the last byte of sum is 0 for each * part (header and data) then the packet is valid. * 'full_size' is the size of the whole packet, including header, updated as soon as the header * is checked and valid */ static void dtplug_protocol_decode(struct dtplug_protocol_handle* handle, uint8_t c) { static uint8_t rx_ptr = 0; static uint8_t sum = 0; static uint8_t full_size = 0; static struct header* info = NULL; status_led(red_on); /* Do not start reception before receiving the packet start character */ if ((rx_ptr == 0) && (c != FIRST_PACKET_CHAR)) { return; } /* Store the new byte in the packet */ if (rx_ptr < sizeof(struct packet)) { ((uint8_t*)handle->rx_packet)[rx_ptr++] = c; sum += c; } else { goto next_packet; } /* Is this packet valid ? (at end of header reception) */ if (rx_ptr == sizeof(struct header)) { if (sum != 0) { goto next_packet; } /* Start the new checksum for data (if any) */ sum = 0; info = (struct header*)handle->rx_packet; full_size = sizeof(struct header); if (!(info->seq_num & QUICK_DATA_PACKET)) { /* Do not care about big data packets here */ full_size += (info->data.size & PKT_SIZE_MASK); } } /* Did we receive the whole packet ? */ if (rx_ptr == full_size) { /* From here on, the packet is valid, we can provide some feedback */ /* Check data checksum */ if (!(info->seq_num & QUICK_DATA_PACKET) && (sum != info->data.checksum)) { dtplug_protocol_add_error_to_list(handle, info, ERROR_IN_DATA_CHECKSUM); handle->errors_count++; goto next_packet; } /* Warning, if we are still using the old packet there's a problem */ if (handle->done_with_old_packet == 0) { /* FIXME : what to do then ? inform the master ? ignore the new packet ? */ dtplug_protocol_add_error_to_list(handle, info, ERROR_LAST_PKT_IN_PROCESS); handle->errors_count++; goto next_packet; } /* Count received packets */ handle->packet_count++; /* Mark packet as OK : switch pointers */ handle->packet_ok = handle->rx_packet; handle->done_with_old_packet = 0; /* Switch our receiving buffer (do not overide the last received packet !) */ if (handle->rx_packet == handle->packets) { handle->rx_packet = handle->packets + 1; } else { handle->rx_packet = handle->packets; } status_led(green_on); /* And get ready to receive the next packet */ goto next_packet; } return; next_packet: #ifdef DEBUG if (handle->done_with_old_packet != 0) { uprintf(handle->uart, "Rx:%d, f:%d, cnt:%d\n", rx_ptr, full_size, handle->packet_count); if (rx_ptr >= sizeof(struct header)) { struct header* h = &(handle->rx_packet->info); uprintf(handle->uart, "P: type:%03d, seq:%d, e:%d, q:%d\n", h->type, h->seq_num, (h->seq_num & PACKET_IS_ERROR), (h->seq_num & QUICK_DATA_PACKET)); } } #endif /* Wether the packet was OK or not doesn't matter, go on for a new one :) */ full_size = 0; rx_ptr = 0; sum = 0; }
void rn42_task(void) { int16_t c; // Raw mode: interpret output report of LED state while ((c = rn42_getc()) != -1) { // LED Out report: 0xFE, 0x02, 0x01, <leds> // To get the report over UART set bit3 with SH, command. static enum {LED_INIT, LED_FE, LED_02, LED_01} state = LED_INIT; switch (state) { case LED_INIT: if (c == 0xFE) state = LED_FE; else { if (0x0 <= c && c <= 0x7f) xprintf("%c", c); else xprintf(" %02X", c); } break; case LED_FE: if (c == 0x02) state = LED_02; else state = LED_INIT; break; case LED_02: if (c == 0x01) state = LED_01; else state = LED_INIT; break; case LED_01: dprintf("LED status: %02X\n", c); rn42_set_leds(c); state = LED_INIT; break; default: state = LED_INIT; } } static uint16_t prev_timer = 0; uint16_t e = timer_elapsed(prev_timer); if (e > 1000) { /* every second */ prev_timer += e/1000*1000; /* Low voltage alert */ uint8_t bs = battery_status(); if (bs == LOW_VOLTAGE) { battery_led(LED_ON); } else { battery_led(LED_CHARGER); } /* every minute */ uint32_t t = timer_read32()/1000; if (t%60 == 0) { uint16_t v = battery_voltage(); uint8_t h = t/3600; uint8_t m = t%3600/60; uint8_t s = t%60; dprintf("%02u:%02u:%02u\t%umV\n", h, m, s, v); } } /* Connection monitor */ if (!rn42_rts() && rn42_linked()) { status_led(true); } else { status_led(false); } }