Skip to content
Snippets Groups Projects
Commit 770601db authored by Cristian Maglie's avatar Cristian Maglie Committed by Cristian Maglie
Browse files

Merge branch 'samba_improvements' into zero

parents 1b908261 a107037c
No related branches found
No related tags found
No related merge requests found
......@@ -750,5 +750,16 @@ uint32_t cdc_read_buf_xmd(void* data, uint32_t length)
return 0;
/* Blocking read till specified number of bytes is received */
return USB_Read_blocking(&pCdc, (char *)data, length);
// XXX: USB_Read_blocking is not reliable
// return USB_Read_blocking(&pCdc, (char *)data, length);
char *dst = (char *)data;
uint32_t remaining = length;
while (remaining) {
uint32_t readed = USB_Read(&pCdc, (char *)dst, remaining);
remaining -= readed;
dst += readed;
}
return length;
}
......@@ -36,6 +36,7 @@
#include "cdc_enumerate.h"
const char RomBOOT_Version[] = SAM_BA_VERSION;
const char RomBOOT_ExtendedCapabilities[] = "[Arduino:XYZ]";
/* Provides one common interface to handle both USART and USB-CDC */
typedef struct
......@@ -166,169 +167,288 @@ uint8_t command, *ptr_data, *ptr, data[SIZEBUFMAX];
uint8_t j;
uint32_t u32tmp;
uint32_t PAGE_SIZE, PAGES, MAX_FLASH;
/**
* \brief This function starts the SAM-BA monitor.
*/
void sam_ba_monitor_run(void)
{
uint32_t pageSizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024 };
PAGE_SIZE = pageSizes[NVMCTRL->PARAM.bit.PSZ];
PAGES = NVMCTRL->PARAM.bit.NVMP;
MAX_FLASH = PAGE_SIZE * PAGES;
ptr_data = NULL;
command = 'z';
// Start waiting some cmd
while (1)
while (1) {
sam_ba_monitor_loop();
}
}
// Prints a 32-bit integer in hex.
void put_uint32(uint32_t n) {
char buff[8];
int i;
for (i=0; i<8; i++) {
int d = n & 0XF;
n = (n >> 4);
buff[7-i] = d > 9 ? 'A' + d - 10 : '0' + d;
}
ptr_monitor_if->putdata(buff, 8);
}
void sam_ba_monitor_loop(void)
{
length = ptr_monitor_if->getdata(data, SIZEBUFMAX);
ptr = data;
for (i = 0; i < length; i++, ptr++)
{
length = ptr_monitor_if->getdata(data, SIZEBUFMAX);
ptr = data;
for (i = 0; i < length; i++)
if (*ptr == 0xff) continue;
if (*ptr == '#')
{
if (*ptr != 0xff)
if (b_terminal_mode)
{
if (*ptr == '#')
ptr_monitor_if->putdata("\n\r", 2);
}
if (command == 'S')
{
//Check if some data are remaining in the "data" buffer
if(length>i)
{
if (b_terminal_mode)
{
ptr_monitor_if->putdata("\n\r", 2);
}
if (command == 'S')
{
//Check if some data are remaining in the "data" buffer
if(length>i)
{
//Move current indexes to next avail data (currently ptr points to "#")
ptr++;
i++;
//We need to add first the remaining data of the current buffer already read from usb
//read a maximum of "current_number" bytes
u32tmp=min((length-i),current_number);
memcpy(ptr_data, ptr, u32tmp);
i += u32tmp;
ptr += u32tmp;
j = u32tmp;
}
//update i with the data read from the buffer
i--;
ptr--;
//Do we expect more data ?
if(j<current_number)
ptr_monitor_if->getdata_xmd(ptr_data, current_number-j);
__asm("nop");
}
else if (command == 'R')
{
ptr_monitor_if->putdata_xmd(ptr_data, current_number);
}
else if (command == 'O')
{
*ptr_data = (char) current_number;
}
else if (command == 'H')
{
*((uint16_t *) ptr_data) = (uint16_t) current_number;
}
else if (command == 'W')
{
*((int *) ptr_data) = current_number;
}
else if (command == 'o')
{
sam_ba_putdata_term(ptr_data, 1);
}
else if (command == 'h')
{
current_number = *((uint16_t *) ptr_data);
sam_ba_putdata_term((uint8_t*) &current_number, 2);
}
else if (command == 'w')
{
current_number = *((uint32_t *) ptr_data);
sam_ba_putdata_term((uint8_t*) &current_number, 4);
}
else if (command == 'G')
{
call_applet(current_number);
/* Rebase the Stack Pointer */
__set_MSP(sp);
cpu_irq_enable();
if (b_sam_ba_interface_usart) {
ptr_monitor_if->put_c(0x6);
}
}
else if (command == 'T')
{
b_terminal_mode = 1;
ptr_monitor_if->putdata("\n\r", 2);
}
else if (command == 'N')
{
if (b_terminal_mode == 0)
{
ptr_monitor_if->putdata("\n\r", 2);
}
b_terminal_mode = 0;
}
else if (command == 'V')
{
ptr_monitor_if->putdata("v", 1);
ptr_monitor_if->putdata((uint8_t *) RomBOOT_Version,
strlen(RomBOOT_Version));
ptr_monitor_if->putdata(" ", 1);
ptr = (uint8_t*) &(__DATE__);
i = 0;
while (*ptr++ != '\0')
i++;
ptr_monitor_if->putdata((uint8_t *) &(__DATE__), i);
ptr_monitor_if->putdata(" ", 1);
i = 0;
ptr = (uint8_t*) &(__TIME__);
while (*ptr++ != '\0')
i++;
ptr_monitor_if->putdata((uint8_t *) &(__TIME__), i);
ptr_monitor_if->putdata("\n\r", 2);
}
//Move current indexes to next avail data (currently ptr points to "#")
ptr++;
i++;
//We need to add first the remaining data of the current buffer already read from usb
//read a maximum of "current_number" bytes
u32tmp=min((length-i),current_number);
memcpy(ptr_data, ptr, u32tmp);
i += u32tmp;
ptr += u32tmp;
j = u32tmp;
}
//update i with the data read from the buffer
i--;
ptr--;
//Do we expect more data ?
if(j<current_number)
ptr_monitor_if->getdata_xmd(ptr_data, current_number-j);
__asm("nop");
}
else if (command == 'R')
{
ptr_monitor_if->putdata_xmd(ptr_data, current_number);
}
else if (command == 'O')
{
*ptr_data = (char) current_number;
}
else if (command == 'H')
{
*((uint16_t *) ptr_data) = (uint16_t) current_number;
}
else if (command == 'W')
{
*((int *) ptr_data) = current_number;
}
else if (command == 'o')
{
sam_ba_putdata_term(ptr_data, 1);
}
else if (command == 'h')
{
current_number = *((uint16_t *) ptr_data);
sam_ba_putdata_term((uint8_t*) &current_number, 2);
}
else if (command == 'w')
{
current_number = *((uint32_t *) ptr_data);
sam_ba_putdata_term((uint8_t*) &current_number, 4);
}
else if (command == 'G')
{
call_applet(current_number);
/* Rebase the Stack Pointer */
__set_MSP(sp);
cpu_irq_enable();
if (b_sam_ba_interface_usart) {
ptr_monitor_if->put_c(0x6);
}
}
else if (command == 'T')
{
b_terminal_mode = 1;
ptr_monitor_if->putdata("\n\r", 2);
}
else if (command == 'N')
{
if (b_terminal_mode == 0)
{
ptr_monitor_if->putdata("\n\r", 2);
}
b_terminal_mode = 0;
}
else if (command == 'V')
{
ptr_monitor_if->putdata("v", 1);
ptr_monitor_if->putdata((uint8_t *) RomBOOT_Version,
strlen(RomBOOT_Version));
ptr_monitor_if->putdata(" ", 1);
ptr_monitor_if->putdata((uint8_t *) RomBOOT_ExtendedCapabilities,
strlen(RomBOOT_ExtendedCapabilities));
ptr_monitor_if->putdata(" ", 1);
ptr = (uint8_t*) &(__DATE__);
i = 0;
while (*ptr++ != '\0')
i++;
ptr_monitor_if->putdata((uint8_t *) &(__DATE__), i);
ptr_monitor_if->putdata(" ", 1);
i = 0;
ptr = (uint8_t*) &(__TIME__);
while (*ptr++ != '\0')
i++;
ptr_monitor_if->putdata((uint8_t *) &(__TIME__), i);
ptr_monitor_if->putdata("\n\r", 2);
}
else if (command == 'X')
{
// Syntax: X[ADDR]#
// Erase the flash memory starting from ADDR to the end of flash.
command = 'z';
current_number = 0;
// Note: the flash memory is erased in ROWS, that is in block of 4 pages.
// Even if the starting address is the last byte of a ROW the entire
// ROW is erased anyway.
if (b_terminal_mode)
{
ptr_monitor_if->putdata(">", 1);
}
uint32_t dst_addr = current_number; // starting address
while (dst_addr < MAX_FLASH) {
// Execute "ER" Erase Row
NVMCTRL->ADDR.reg = dst_addr / 2;
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER;
while (NVMCTRL->INTFLAG.bit.READY == 0)
;
dst_addr += PAGE_SIZE * 4; // Skip a ROW
}
else
{
if (('0' <= *ptr) && (*ptr <= '9'))
{
current_number = (current_number << 4) | (*ptr - '0');
}
else if (('A' <= *ptr) && (*ptr <= 'F'))
{
current_number = (current_number << 4)
| (*ptr - 'A' + 0xa);
// Notify command completed
ptr_monitor_if->putdata("X\n\r", 3);
}
else if (command == 'Y')
{
// This command writes the content of a buffer in SRAM into flash memory.
}
else if (('a' <= *ptr) && (*ptr <= 'f'))
{
current_number = (current_number << 4)
| (*ptr - 'a' + 0xa);
// Syntax: Y[ADDR],0#
// Set the starting address of the SRAM buffer.
}
else if (*ptr == ',')
{
ptr_data = (uint8_t *) current_number;
current_number = 0;
// Syntax: Y[ROM_ADDR],[SIZE]#
// Write the first SIZE bytes from the SRAM buffer (previously set) into
// flash memory starting from address ROM_ADDR
}
else
{
command = *ptr;
current_number = 0;
static uint32_t *src_buff_addr = NULL;
if (current_number == 0) {
// Set buffer address
src_buff_addr = ptr_data;
} else {
// Write to flash
uint32_t size = current_number/4;
uint32_t *src_addr = src_buff_addr;
uint32_t *dst_addr = ptr_data;
// Set automatic page write
NVMCTRL->CTRLB.bit.MANW = 0;
// Do writes in pages
while (size) {
// Execute "PBC" Page Buffer Clear
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC;
while (NVMCTRL->INTFLAG.bit.READY == 0)
;
// Fill page buffer
uint32_t i;
for (i=0; i<(PAGE_SIZE/4) && i<size; i++) {
dst_addr[i] = src_addr[i];
}
// Execute "WP" Write Page
//NVMCTRL->ADDR.reg = ((uint32_t)dst_addr) / 2;
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP;
while (NVMCTRL->INTFLAG.bit.READY == 0)
;
// Advance to next page
dst_addr += i;
src_addr += i;
size -= i;
}
}
ptr++;
// Notify command completed
ptr_monitor_if->putdata("Y\n\r", 3);
}
else if (command == 'Z')
{
// This command calculate CRC for a given area of memory.
// It's useful to quickly check if a transfer has been done
// successfully.
// Syntax: Z[START_ADDR],[SIZE]#
// Returns: Z[CRC]#
uint8_t *data = (uint8_t *)ptr_data;
uint32_t size = current_number;
uint16_t crc = 0;
uint32_t i = 0;
for (i=0; i<size; i++)
crc = add_crc(*data++, crc);
// Send response
ptr_monitor_if->putdata("Z", 1);
put_uint32(crc);
ptr_monitor_if->putdata("#\n\r", 3);
}
command = 'z';
current_number = 0;
if (b_terminal_mode)
{
ptr_monitor_if->putdata(">", 1);
}
}
else
{
if (('0' <= *ptr) && (*ptr <= '9'))
{
current_number = (current_number << 4) | (*ptr - '0');
}
else if (('A' <= *ptr) && (*ptr <= 'F'))
{
current_number = (current_number << 4) | (*ptr - 'A' + 0xa);
}
else if (('a' <= *ptr) && (*ptr <= 'f'))
{
current_number = (current_number << 4) | (*ptr - 'a' + 0xa);
}
else if (*ptr == ',')
{
ptr_data = (uint8_t *) current_number;
current_number = 0;
}
else
{
command = *ptr;
current_number = 0;
}
}
}
}
No preview for this file type
......@@ -203,24 +203,47 @@ uint32_t usart_getdata(void* data, uint32_t length) {
return (1);
}
static const uint16_t crc16Table[256] = {
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
};
//*----------------------------------------------------------------------------
//* \fn add_crc
//* \brief Compute the CRC
//*----------------------------------------------------------------------------
unsigned short add_crc(char ptr, unsigned short crc) {
unsigned short cmpt;
crc = crc ^ (int) ptr << 8;
for (cmpt = 0; cmpt < 8; cmpt++) {
if (crc & 0x8000)
crc = crc << 1 ^ CRC16POLY;
else
crc = crc << 1;
}
return (crc & 0xFFFF);
return (crc << 8) ^ crc16Table[((crc >> 8) ^ ptr) & 0xff];
}
//*----------------------------------------------------------------------------
......
......@@ -142,13 +142,13 @@ uint32_t usart_putdata_xmd(void const* data, uint32_t length); //Send given data
uint32_t usart_getdata_xmd(void* data, uint32_t length); //Get data from comm. device using xmodem (if necessary)
/**
* \brief Gets data from usart line using Xmodem protocol
* \brief Compute the CRC
*
* \param data pointer
* \param number of data to get
* \return value read on usart line
* \param Char to add to CRC
* \param Previous CRC
* \return The new computed CRC
*/
unsigned short add_crc(char ptr, unsigned short crc);
unsigned short add_crc(char c, unsigned short crc);
uint8_t getPacket(uint8_t *pData, uint8_t sno);
......
......@@ -80,7 +80,7 @@ recipe.size.regex=\.text\s+([0-9]+).*
#
tools.bossac.cmd=bossac
tools.bossac.cmd.windows=bossac.exe
tools.bossac.path={runtime.ide.path}/hardware/tools/bossac-1.4-arduino
tools.bossac.path={runtime.ide.path}/hardware/tools/bossac-1.5-arduino
tools.bossac.upload.params.verbose=-i -d
tools.bossac.upload.params.quiet=
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment