int main(void) { uint8_t rxByte; init(); // main loop while (1) { // poll and retransmit while waiting for the sync byte while ((rxByte = usart_getchar(USART_SERIAL)) != RENARD_SYNC) { usart_serial_putchar(USART_SERIAL, rxByte); } // retransmit the sync byte usart_serial_putchar(USART_SERIAL, RENARD_SYNC); // evaluate command byte usart_serial_getchar(USART_SERIAL, &rxByte); if (rxByte == RENARD_ADDR) { // process renard packet for this device procRenard(); } else if (rxByte > RENARD_ADDR) { // decrement command/address byte and transmit rxByte--; usart_serial_putchar(USART_SERIAL, rxByte); } else { // unsupported / reserved. retransmit usart_serial_putchar(USART_SERIAL, rxByte); } } }
/** * \brief Receive the files through XMODEM protocol * * \param usart Base address of the USART instance. * \param p_buffer Pointer to receive buffer * * \return received file size */ uint32_t xmodem_receive_file(usart_if usart, int8_t *p_buffer) { uint32_t ul_timeout; uint8_t c_char; int32_t l_done; uint8_t uc_sno = 0x01; uint32_t ul_size = 0; /* Wait and put 'C' till start XMODEM transfer */ while (1) { usart_serial_putchar(usart, 'C'); ul_timeout = (sysclk_get_peripheral_hz() / 10); while (!(usart_serial_is_rx_ready(usart)) && ul_timeout) { ul_timeout--; } if (usart_serial_is_rx_ready(usart)) { break; } } /* Begin to receive the data */ l_done = 0; while (l_done == 0) { usart_serial_getchar(usart, &c_char); switch (c_char) { /* Start of transfer */ case XMDM_SOH: l_done = xmodem_get_packet(usart, p_buffer+ul_size, uc_sno); if (l_done == 0) { uc_sno++; ul_size += PKTLEN_128; } usart_serial_putchar(usart, XMDM_ACK); break; /* End of transfer */ case XMDM_EOT: usart_serial_putchar(usart, XMDM_ACK); l_done = ul_size; break; case XMDM_CAN: case XMDM_ESC: default: l_done = -1; break; } } return ul_size; }
/** * \brief Get a packet through XMODEM protocol * * \param usart Base address of the USART instance. * \param p_data Pointer to the data buffer. * \param uc_sno Sequnce number. * * \return 0 for sucess and other value for XMODEM error */ static int32_t xmodem_get_packet(usart_if usart, int8_t *p_data, uint8_t uc_sno) { uint8_t uc_cp_seq[2], uc_temp[2]; uint16_t us_crc, us_xcrc; xmodem_get_bytes(usart, (int8_t *)uc_cp_seq, 2); us_xcrc = xmodem_get_bytes(usart, p_data, PKTLEN_128); /* An "endian independent way to combine the CRC bytes. */ usart_serial_getchar(usart, &uc_temp[0]); usart_serial_getchar(usart, &uc_temp[1]); us_crc = uc_temp[0] << 8; us_crc += uc_temp[1]; if ((us_crc != us_xcrc) || (uc_cp_seq[0] != uc_sno) || (uc_cp_seq[1] != (uint8_t) ((~(uint32_t)uc_sno) & 0xff))) { usart_serial_putchar(usart, XMDM_CAN); return (-1); } return 0; }
/** * \brief Send the files through XMODEM protocol * * \param usart Base address of the USART instance. * \param p_buffer Pointer to send buffer * \param ul_length transfer file size */ void xmodem_send_file(usart_if usart, int8_t *p_buffer, uint32_t ul_length) { uint8_t c_char, uc_sno = 1; int32_t l_done; uint32_t ul_timeout = (sysclk_get_peripheral_hz() / 10); if (ul_length & (PKTLEN_128-1)) { ul_length += PKTLEN_128; ul_length &= ~(PKTLEN_128-1); } /* Startup synchronization... */ /* Wait to receive a NAK or 'C' from receiver. */ l_done = 0; while(!l_done) { usart_serial_getchar(usart, &c_char); switch (c_char) { case XMDM_NAK: l_done = 1; break; case 'C': l_done = 1; break; case 'q': /* ELS addition, not part of XMODEM spec. */ return; default: break; } } l_done = 0; uc_sno = 1; while (!l_done) { c_char = xmodem_send_packet(usart, (uint8_t *)p_buffer, uc_sno); switch(c_char) { case XMDM_ACK: ++uc_sno; ul_length -= PKTLEN_128; p_buffer += PKTLEN_128; break; case XMDM_NAK: break; case XMDM_CAN: case XMDM_EOT: default: l_done = -1; break; } if (!ul_length) { usart_serial_putchar(usart, XMDM_EOT); /* Flush the ACK */ usart_serial_getchar(usart, &c_char); break; } } }
/** * \brief Send a sequence of bytes to USART device * * \param usart Base address of the USART instance. * \param data Data buffer to read * \param len Length of data * */ status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data, size_t len) { while (len) { usart_serial_putchar(usart, *data); len--; data++; } return STATUS_OK; }
/** * \brief Send a packet through XMODEM protocol * * \param usart Base address of the USART instance. * \param p_data Pointer to the data buffer. * \param uc_sno Sequnce number. * * \return 0 for sucess and other value for XMODEM error */ static uint8_t xmodem_send_packet(usart_if usart, uint8_t *p_data, uint8_t uc_sno) { uint32_t i, j; uint16_t us_check_sum; int8_t c_data; uint8_t uc_ack; us_check_sum = 0; usart_serial_putchar(usart, XMDM_SOH); usart_serial_putchar(usart, uc_sno); usart_serial_putchar(usart, ((uint8_t)(~(uc_sno)))); for(i = 0; i < PKTLEN_128; i++) { c_data = *p_data++; usart_serial_putchar(usart, c_data); us_check_sum = us_check_sum ^ (int32_t) c_data << 8; for (j = 0; j < 8; j++) { if (us_check_sum & 0x8000) { us_check_sum = us_check_sum << 1 ^ CRC16POLY; } else { us_check_sum = us_check_sum << 1; } } us_check_sum = us_check_sum & 0xFFFF; } /* An "endian independent way to extract the CRC bytes. */ usart_serial_putchar(usart, (uint8_t)(us_check_sum >> 8)); usart_serial_putchar(usart, (uint8_t)us_check_sum); usart_serial_getchar(usart, &uc_ack); return uc_ack; /* Wait for ack */ }
BaseOutStream& USARTStream::put(char_type ch) { usart_serial_putchar(usart, ch); return *this; }
void USARTStream::newline() { usart_serial_putchar(usart, '\r'); usart_serial_putchar(usart, '\n'); }
int wifi_send_cmd(const char* cmd, const char* resp_complete, char* resp, uint32_t maxlen, int timeout){ resp_buf_idx = 0; uint32_t rx_start, rx_end; //clear out the response buffer memset(resp,0x0,maxlen); memset(resp_buf,0x0,RESP_BUF_SIZE); //setup the rx_complete buffer so we know when the command is finished if(strlen(resp_complete)>RESP_COMPLETE_BUF_SIZE-3){ printf("resp_complete, too long exiting\n"); return -1; } strcpy(resp_complete_buf,resp_complete); strcat(resp_complete_buf,"\r\n"); //enable RX interrupts usart_enable_interrupt(WIFI_UART, US_IER_RXRDY); NVIC_SetPriority(WIFI_UART_IRQ,2); NVIC_EnableIRQ(WIFI_UART_IRQ); //write the command rx_wait=true; //we want this data returned in resp_buf rx_complete =false; //reset the early complete flag usart_serial_write_packet(WIFI_UART,(uint8_t*)cmd,strlen(cmd)); //terminate the command usart_serial_putchar(WIFI_UART,'\r'); usart_serial_putchar(WIFI_UART,'\n'); //wait for [timeout] seconds while(timeout>0){ //start the timer tc_start(TC0, 0); //when timer expires, return what we have in the buffer rx_wait=true; //reset the wait flag while(rx_wait); tc_stop(TC0,0); if(rx_complete) //if the uart interrupt signals rx is complete break; timeout--; } //now null terminate the response resp_buf[resp_buf_idx]=0x0; //remove any ECHO if(strstr((char*)resp_buf,cmd)!=(char*)resp_buf){ printf("bad echo: %s\n",resp_buf); return 0; } rx_start = strlen(cmd); //remove leading whitespace while(resp_buf[rx_start]=='\r'|| resp_buf[rx_start]=='\n') rx_start++; //remove trailing whitespace rx_end = strlen((char*)resp_buf)-1; while(resp_buf[rx_end]=='\r'|| resp_buf[rx_end]=='\n') rx_end--; //make sure we have a response if(rx_end<=rx_start){ printf("no response by timeout\n"); return 0; } //copy the data to the response buffer if((rx_end-rx_start+1)>maxlen){ memcpy(resp,&resp_buf[rx_start],maxlen-1); resp[maxlen-1]=0x0; printf((char*)resp_buf); printf("truncated output!\n"); } else{ memcpy(resp,&resp_buf[rx_start],rx_end-rx_start+1); //null terminate the response buffer resp[rx_end-rx_start+1]=0x0; } return rx_end-rx_start; }
/** * Put a byte to console * \param c The byte to put */ void dbg_usart_putchar(uint8_t c) { usart_serial_putchar(DBG_USART_BASE, c); }