Example #1
0
/* NOTE: Automatic deduction of the number of blocks, that need to be erased 
         has not been tested extensive. */
void upload() {

   uint size;           // Image size.
   uint step;           // Progress bar step size.
   uint cval;           // Current progress value.

   // Clear screen.
   cls();

   // User Upload Menu.
   drawWindow(&wUpload);

   // Upload Initialization.
   drawMessage(&wUpload, &msgUploadWait); 
   pbUpload.val = 0;   
   drawProgressBar(&wUpload, &pbUpload);
   
   // Receive 4 bytes of size data.
   for(uchar i=0; i < 4; i++) {
      size <<= 8;
      size += rs232_receive();
   }

   // Check for image size to fit into flash.
   if(size > FLASH_BLOCK_SIZE * FLASH_BLOCKS) {
      drawErrorWindow(&errErrorFlashSize);
      return 0;
   }

   // Flash Clean Up.
   drawMessage(&wUpload, &msgUploadErase);
   pbUpload.val = 0;                         // Reset progress bar.
   drawProgressBar(&wUpload, &pbUpload);
   
   // Erase affected flash blocks.
   for(uint i=0; i < (size / FLASH_BLOCK_SIZE) + 1; i++) {
      flash_block_erase(i * FLASH_BLOCK_SIZE);

      // Update the Progress Bar.
      pbUpload.val = (i >> 1);
      drawProgressBar(&wUpload, &pbUpload);

      // Check for errors while erasing.
      if(flash_wait() & FLASH_ERASE_ERROR) {
         drawErrorWindow(&errErrorFlashErase);
         return 0;
      }
   }
   
   // Write image size at flash address 0x0.
   for(uchar i=0; i<4; i++) {
      flash_write(i, size >> ((3-i) * 8) );
      checkFlashWrite();
   }

   // Upload data.
   drawMessage(&wUpload, &msgUploadWrite);
   pbUpload.val = 0;                         // Reset progress bar.
   step = size / 64;                         // Calculate progress step size.
   cval = step;

   // Echoing received image size.
   for(uchar i=0; i<4; i++) {
      rs232_transmit( size >> ((3-i) * 8) );
   }
   
   // Write each single byte to Flash.
   for(uint i=0; i < size; i++) {
      flash_write(i + 4, rs232_receive());

      // Update status bar.
      if(i == cval) {
         pbUpload.val++;
         drawProgressBar(&wUpload, &pbUpload);
         cval += step;
      }

      checkFlashWrite();
   }

   // Go back to main menu.
   boot();
}
Example #2
0
static void cmd_handler(uint8_t dlci, struct msgb *msg)
{
	if (msg->data_len < 1) {
		return;
	}

	uint8_t command = msgb_pull_u8(msg);

	int res = 0;

	flash_lock_t lock;

	void *data;

	uint8_t chip;
	uint8_t nbytes;
	uint16_t crc, mycrc;
	uint32_t address;

	struct msgb *reply = sercomm_alloc_msgb(256);	// XXX

	if (!reply) {
		printf("Failed to allocate reply buffer!\n");
		goto out;
	}

	switch (command) {

	case LOADER_PING:
		loader_send_simple(reply, dlci, LOADER_PING);
		break;

	case LOADER_RESET:
		loader_send_simple(reply, dlci, LOADER_RESET);
		device_reset();
		break;

	case LOADER_POWEROFF:
		loader_send_simple(reply, dlci, LOADER_POWEROFF);
		device_poweroff();
		break;

	case LOADER_ENTER_ROM_LOADER:
		loader_send_simple(reply, dlci, LOADER_ENTER_ROM_LOADER);
		device_enter_loader(1);
		break;

	case LOADER_ENTER_FLASH_LOADER:
		loader_send_simple(reply, dlci, LOADER_ENTER_FLASH_LOADER);
		device_enter_loader(0);
		break;

	case LOADER_MEM_READ:

		nbytes = msgb_pull_u8(msg);
		address = msgb_pull_u32(msg);

		crc = osmo_crc16(0, (void *)address, nbytes);

		msgb_put_u8(reply, LOADER_MEM_READ);
		msgb_put_u8(reply, nbytes);
		msgb_put_u16(reply, crc);
		msgb_put_u32(reply, address);

		memcpy(msgb_put(reply, nbytes), (void *)address, nbytes);

		sercomm_sendmsg(dlci, reply);

		break;

	case LOADER_MEM_WRITE:

		nbytes = msgb_pull_u8(msg);
		crc = msgb_pull_u16(msg);
		address = msgb_pull_u32(msg);

		data = msgb_pull(msg, nbytes) - nbytes;

		mycrc = osmo_crc16(0, data, nbytes);

		if (mycrc == crc) {
			memcpy((void *)address, data, nbytes);
		}

		msgb_put_u8(reply, LOADER_MEM_WRITE);
		msgb_put_u8(reply, nbytes);
		msgb_put_u16(reply, mycrc);
		msgb_put_u32(reply, address);

		sercomm_sendmsg(dlci, reply);

		break;

	case LOADER_JUMP:

		address = msgb_pull_u32(msg);

		msgb_put_u8(reply, LOADER_JUMP);
		msgb_put_u32(reply, address);

		sercomm_sendmsg(dlci, reply);

		device_jump((void *)address);

		break;

	case LOADER_FLASH_INFO:

		msgb_put_u8(reply, LOADER_FLASH_INFO);
		msgb_put_u8(reply, 1);	// nchips

		// chip 1
		msgb_put_u32(reply, (uint32_t)the_flash.f_base);
		msgb_put_u32(reply, the_flash.f_size);
		msgb_put_u8(reply, the_flash.f_nregions);

		unsigned i;
		for (i = 0; i < the_flash.f_nregions; i++) {
			msgb_put_u32(reply, the_flash.f_regions[i].fr_bnum);
			msgb_put_u32(reply, the_flash.f_regions[i].fr_bsize);
		}

		sercomm_sendmsg(dlci, reply);

		break;

	case LOADER_FLASH_ERASE:
	case LOADER_FLASH_UNLOCK:
	case LOADER_FLASH_LOCK:
	case LOADER_FLASH_LOCKDOWN:

		chip = msgb_pull_u8(msg);
		address = msgb_pull_u32(msg);

		if (command == LOADER_FLASH_ERASE) {
			res = flash_block_erase(&the_flash, address);
		}
		if (command == LOADER_FLASH_UNLOCK) {
			res = flash_block_unlock(&the_flash, address);
		}
		if (command == LOADER_FLASH_LOCK) {
			res = flash_block_lock(&the_flash, address);
		}
		if (command == LOADER_FLASH_LOCKDOWN) {
			res = flash_block_lockdown(&the_flash, address);
		}

		msgb_put_u8(reply, command);
		msgb_put_u8(reply, chip);
		msgb_put_u32(reply, address);
		msgb_put_u32(reply, (res != 0));

		sercomm_sendmsg(dlci, reply);

		break;

	case LOADER_FLASH_GETLOCK:

		chip = msgb_pull_u8(msg);
		address = msgb_pull_u32(msg);

		lock = flash_block_getlock(&the_flash, address);

		msgb_put_u8(reply, command);
		msgb_put_u8(reply, chip);
		msgb_put_u32(reply, address);

		switch (lock) {
		case FLASH_UNLOCKED:
			msgb_put_u32(reply, LOADER_FLASH_UNLOCKED);
			break;
		case FLASH_LOCKED:
			msgb_put_u32(reply, LOADER_FLASH_LOCKED);
			break;
		case FLASH_LOCKED_DOWN:
			msgb_put_u32(reply, LOADER_FLASH_LOCKED_DOWN);
			break;
		default:
			msgb_put_u32(reply, 0xFFFFFFFF);
			break;
		}

		sercomm_sendmsg(dlci, reply);

		break;

	case LOADER_FLASH_PROGRAM:

		nbytes = msgb_pull_u8(msg);
		crc = msgb_pull_u16(msg);
		msgb_pull_u8(msg);	// XXX align
		chip = msgb_pull_u8(msg);
		address = msgb_pull_u32(msg);

		data = msgb_pull(msg, nbytes) - nbytes;

		mycrc = osmo_crc16(0, data, nbytes);

		if (mycrc == crc) {
			res = flash_program(&the_flash, address, data, nbytes);
		}

		msgb_put_u8(reply, LOADER_FLASH_PROGRAM);
		msgb_put_u8(reply, nbytes);
		msgb_put_u16(reply, mycrc);
		msgb_put_u8(reply, 0);	// XXX align
		msgb_put_u8(reply, chip);
		msgb_put_u32(reply, address);

		msgb_put_u32(reply, (uint32_t) res);	// XXX

		sercomm_sendmsg(dlci, reply);

		break;

	default:
		printf("unknown command %d\n", command);

		msgb_free(reply);

		break;
	}

 out:

	msgb_free(msg);
}