Ejemplo n.º 1
0
/*
 * generate_and_store_mac_addr()
 * 
 * This routine is called when, upon program initialization, we discover
 * that there is no valid network settings (including MAC address) programmed
 * into flash memory at the last flash sector.  If it is not safe to use the 
 * contents of this last sector of flash, the user is prompted to
 * enter the serial number at the console.  A MAC address is then
 * generated using 0xFF followed by the last 2 bytes of the serial number 
 * appended to Altera's Vendor ID, an assigned MAC address range with the first
 * 3 bytes of 00:07:ED.  For example, if the Nios Development Board serial 
 * number is 040800017, the corresponding ethernet number generated will be
 * 00:07:ED:FF:8F:11.
 * 
 * It should be noted that this number, while unique, will likely differ from
 * the also unique (but now lost forever) MAC address programmed into the 
 * development board on the production line.
 * 
 * As we are erasing the entire flash sector, we'll re-program it with not
 * only the MAC address, but static IP, subnet, gateway, and "Use DHCP" 
 * sections. These fail-safe static settings are compatible with previous
 * Nios Ethernet designs, and allow the "factory-safe" design to behave 
 * as expected if the last flash sector is erased.
 */
error_t generate_and_store_mac_addr()
{
  error_t error = -1;
  alt_u32 ser_num = 0;
  char serial_number[9], flash_content[32];
  alt_flash_fd* flash_handle;
  int i = 0;
  
  printf("Can't read the MAC address from your board (this probably means\n");
  printf("that your flash was erased). We will assign you a MAC address and\n");
  printf("static network settings\n\n");
  
  while(!ser_num)
  {
    printf("Please enter your 9-digit serial number. This is printed on a \n");
    printf("label under your Nios dev. board. The first 3 digits of the \n");
    printf("label are ASJ and the serial number follows this.\n -->");
    
    for(i=0; i<9; i++)
    {
      serial_number[i] = getchar();
      putchar(serial_number[i]);
      
      /* Handle backspaces.  How civilized. */
      if ((serial_number[i] == 0x08) && (i >= 0)) 
      {
        i--;
      }
    }
    printf("\n");
            
    for(i=0; i<9; i++)
    {
      if (isdigit(serial_number[i]))
      {
        ser_num *= 10;
        ser_num += serial_number[i] - '0';
      }
      else
      {
        ser_num = 0;
        printf("Serial number only contains decimal digits and is non-zero\n");
        break;
      }
    }
    
    if (ser_num)
    {
      /* This says the image is safe */
      flash_content[0] = 0xfe;
      flash_content[1] = 0x5a;
      flash_content[2] = 0x0;
      flash_content[3] = 0x0;
      
      /* This is the Altera Vendor ID */
      flash_content[4] = 0x0;
      flash_content[5] = 0x7;
      flash_content[6] = 0xed;
      
      /* Reserverd Board identifier for erase boards */
      flash_content[7] = 0xFF;
      flash_content[8] = (ser_num & 0xff00) >> 8;
      flash_content[9] = ser_num & 0xff;

      /* Then comes a 16-bit "flags" field */
      flash_content[10] = 0xFF;
      flash_content[11] = 0xFF;
      
      /* Then comes the static IP address */
      flash_content[12] = IPADDR0;
      flash_content[13] = IPADDR1;
      flash_content[14] = IPADDR2;
      flash_content[15] = IPADDR3;
      
      /* Then comes the static nameserver address */
      flash_content[16] = 0xFF;
      flash_content[17] = 0xFF;
      flash_content[18] = 0xFF;
      flash_content[19] = 0xFF;
      
      /* Then comes the static subnet mask */
      flash_content[20] = MSKADDR0;
      flash_content[21] = MSKADDR1;
      flash_content[22] = MSKADDR2;
      flash_content[23] = MSKADDR3;
      
      /* Then comes the static gateway address */
      flash_content[24] = GWADDR0;
      flash_content[25] = GWADDR1;
      flash_content[26] = GWADDR2;
      flash_content[27] = GWADDR3;
      
      /* And finally whether to use DHCP - set all bits to be safe */
      flash_content[28] = 0xFF;
      flash_content[29] = 0xFF;
      flash_content[30] = 0xFF;
      flash_content[31] = 0xFF;
      
      /* Write the MAC address to flash */
      flash_handle = alt_flash_open_dev(EXT_FLASH_NAME);
      if (flash_handle)
      {
        alt_write_flash(flash_handle,
                        ETHERNET_OPTION_BITS,
                        flash_content,
                        32);
        alt_flash_close_dev(flash_handle);
        error = 0;
      }
    }
  }
  return error;    
}
Ejemplo n.º 2
0
bool Flash_Write(FLASH_HANDLE Handle, alt_u32 offset, alt_u8 *szData, alt_u32 size){
    FLASH_INFO *pFlash = (FLASH_INFO *)Handle;
    bool bSuccess = TRUE;
    int error_code;
    
    if (!pFlash->fd_flash)
        return FALSE;
    //FLASH_DEBUG(("Flash_Write, offset=%d, size=%d\r\n", offset, size));
#if 0
    error_code = alt_write_flash(fd_flash, offset, szData, size); // note. !!!! it will erase flash block content before write data
    if (error_code == 0){
        bSuccess = TRUE;
    }else{
        FLASH_DEBUG(("alt_write_flash fail, error_code=%d\r\n", error_code));
    }    
#else
    int block_offset, block_size, write_count, this_write_size, r, i;//, first_offset;        
    flash_region *nextreg = pFlash->regions_flash;

    
    block_offset = 0;
    write_count = 0;
    for(r=0;r<pFlash->number_of_regions_flash && bSuccess;r++){
        for(i=0;i<nextreg->number_of_blocks && bSuccess;i++){
            block_size = nextreg->block_size;
//            FLASH_DEBUG(("block_offset=%d, block_size=%d\r\n", block_offset, block_size));
//            if ((offset >= block_offset) && ((offset+size) <= (block_offset + block_size))){
            if (((offset+write_count) >= block_offset) && (write_count < size)){
                // write
                this_write_size = size - write_count;
                if (write_count == 0){
                    // first block
                    if (this_write_size > (block_offset + block_size - offset))
                        this_write_size = block_offset + block_size - offset;
                }else{
                    // block aligement
                    if (this_write_size > block_size)
                        this_write_size = block_size;
                }        
                error_code = alt_write_flash_block(pFlash->fd_flash, block_offset, offset+write_count, szData+write_count, this_write_size);
                //FLASH_DEBUG(("alt_write_flash_block, block_offset:%d, offset:%d, len:%d, this block_size:%d\r\n", block_offset, offset+write_count, this_write_size, block_size));
                if (error_code != 0){
                    bSuccess = FALSE;
                    FLASH_DEBUG(("alt_write_flash_block fail, error_code=%d\r\n", error_code));
                }    
                write_count += this_write_size;
            }
            block_offset += block_size;
        }
        nextreg++;
    }      
#endif      
        
/*        
    error_code = alt_write_flash(fd_flash, offset, szData, size); // it will erase flash block content before write data
//    error_code = alt_write_flash_block(fd_flash, offset, offset+size, szData, size); // it will preserve flash content
    if (error_code == 0)
        return TRUE;
*/        
    return bSuccess;                    
}
Ejemplo n.º 3
0
Archivo: main.c Proyecto: gri6507/QMS
static void ExecuteCmd(const char const *input, const u32 base)
{
    SendStr("\r\n", base);
    
    // Tokenize the command
    #define MAX_CMD_WORDS 4
    char *token[MAX_CMD_WORDS];
    char *cmd = (char *)input;
    u8 numTokens = 0;
    while (1)
    {
        // Skip leading whitespace.
        while ((*cmd) && isspace(*cmd))
            cmd++;

        // If we get here and we are at the end of the string, then the last
        // token must have had trailing white spaces. Let's ignore them
        if (!(*cmd))
            break;

        // If we have exceeded the maximum number of allowable tokens, then
        // return as error
        if (numTokens >= MAX_CMD_WORDS)
        {
            SendStr(NO_ANSWER, base);
            return;
        }

        // Store the token.
        token[numTokens] = cmd;
        numTokens++;

        // Everything that isn't a whitespace is part of the token. Let's make
        // sure it is in UPPER CASE
        while ((*cmd) && (!isspace(*cmd)))
        {
            *cmd = toupper(*cmd);
            cmd++;
        }

        // When we get here, we are just past the current token, either because
        // it ended on a whitespace or because it is the end of the user input.
        // If the former, then let's force a null termination for that token. If
        // the latter, then we are done tokenizing.
        if (!(*cmd))
            break;
        *cmd = '\0';
        cmd++;
    }
    
    if (0 == numTokens)
    {
        SendStr(NO_ANSWER, base);
        return;
    }
    
    // Process the command
    switch (token[0][0])
    {
        case 'R':
        {
            if (2 != numTokens)
                SendStr(NO_ANSWER, base);
            else
            {
                u32 regAddr;
                u32 regValue;
                if (StrToU32(token[1], &regAddr) && RegRead(regAddr, &regValue))
                {
                    SendStr("Y ", base);
                    char regValStr[9];
                    U32ToStr(regValue, regValStr);
                    SendStr(regValStr, base);
                    SendStr("\r\n", base);
                }
                else
                    SendStr(NO_ANSWER, base);
            }
            break;
        }
            
        case 'W':
        {
            if (3 != numTokens)
                SendStr(NO_ANSWER, base);
            else
            {
                u32 regAddr;
                u32 regValue;
                if (StrToU32(token[1], &regAddr) && StrToU32(token[2], &regValue) && RegWrite(regAddr, regValue))
                    SendStr(YES_ANSWER, base);
                else
                    SendStr(NO_ANSWER, base);
            }
            break;
        }
        
        case 'V':
        {
            SendStr("FPGA=0x", base);
            char versionStr[9];
            FpgaRegisters * FPGARegs = (FpgaRegisters *)(REGISTER_BASE | BYPASS_DCACHE_MASK);
            U32ToStr(FPGARegs->fpgaVersion, versionStr);
            SendStr(versionStr, base);
            SendStr(" NIOS=0x", base);
            U32ToStr(NIOS_VERSION, versionStr);
            SendStr(versionStr, base);
            SendStr("\r\n", base);
            break;
        }

        case 'F':
        {
            if (4 != numTokens)
                SendStr(NO_ANSWER, base);
            else
            {
                u32 startAddr;
                u32 length;
                u32 checksum;
                StrToU32(token[1], &startAddr);
                StrToU32(token[2], &length);
                StrToU32(token[3], &checksum);

                // Transfer two chunks to get a full sector worth
				#define FLASH_SECTOR_SIZE (64*1024)
				#define TRANSFER_SIZE     (4*1024)
                u8  buffer[FLASH_SECTOR_SIZE];

                // Validate the requested transfer size
                if (length != TRANSFER_SIZE)
                    SendStr(NO_ANSWER, base);
                else
                {
                    u32 bufferIndex = startAddr % FLASH_SECTOR_SIZE;
                    u32 runningSum = 0;
                    u32 numBytesReceived = 0;

                	// Clear the input buffer
                	FlushRx(base);

                    // Acknowledge that the command is good. This will tell the
                    // sender to actually send the specified number of bytes
                    SendStr(YES_ANSWER, base);

                    // We must receive the correct number of bytes
                    while (true)
                    {
                    	while (IORD_FIFOED_AVALON_UART_STATUS(base) & FIFOED_AVALON_UART_CONTROL_RRDY_MSK)
                    	{
							// Read the Uart
							u8 rx = IORD_FIFOED_AVALON_UART_RXDATA(base);
							runningSum += rx;
							buffer[bufferIndex++] = rx;
							numBytesReceived++;
	                        if (numBytesReceived >= length)
	                            break;
                    	}
                        if (numBytesReceived >= length)
                            break;
                    }

                    // check the checksum
                    if (runningSum != checksum)
                        SendStr(NO_ANSWER, base);
                    else
                    {
                    	// If we don't have a full sector worth of data, then ACK and wait for more
                    	if (bufferIndex != FLASH_SECTOR_SIZE)
                    		SendStr(YES_ANSWER, base);
                    	else
                    	{
                    		u32 totalWriteBufferChecksum = 0;
                    		int i;
                    		for (i=0; i<sizeof(buffer); i++)
                    		{
                    			totalWriteBufferChecksum += buffer[i];
                    		}

							alt_flash_fd* fd = alt_flash_open_dev(SERIAL_FLASH_NAME);
							if (NULL == fd)
								SendStr(NO_ANSWER, base);
							else
							{
								u32 sectorStartAddr = (startAddr / FLASH_SECTOR_SIZE) * FLASH_SECTOR_SIZE;
								if (0 == alt_write_flash(fd, sectorStartAddr, buffer, length))
								{
									memset(buffer, 0x99, sizeof(buffer));
									if (0 == alt_read_flash(fd, sectorStartAddr, buffer, sizeof(buffer)))
									{
			                    		u32 totalReadBufferChecksum = 0;
			                    		for (i=0; i<sizeof(buffer); i++)
			                    		{
			                    			totalReadBufferChecksum += buffer[i];
			                    		}
			                    		if (totalReadBufferChecksum == totalWriteBufferChecksum)
											SendStr(YES_ANSWER, base);
			                    		else
											SendStr(NO_ANSWER, base);
									}
		                    		else
										SendStr(NO_ANSWER, base);
								}
								else
									SendStr(NO_ANSWER, base);

								alt_flash_close_dev(fd);
							}
                    	}
                    }
                }
            }

            break;
        }
            
        default:
            SendStr(NO_ANSWER, base);
            break;
    }
    
    return;
}
Ejemplo n.º 4
0
/******************************************************************
*  Function: FlashTestReadWrite
*
*  Purpose: Tests that the functions alt_write_flash and
*           alt_read_flash are working properly, as well as tests
*           that every bit in the specified block can store both
*           a '1' and '0'.
*
******************************************************************/
static int FlashTestReadWrite(int block, int *error, alt_flash_fd* fd, flash_region* regions)
{
  int i;
  int ret_code = 0x0;
  int test_offset;

  alt_u8 *data_written;
  alt_u8 *data_read;
 

  /* Get a couple buffers for the tests */
  data_written = malloc(regions->block_size);
  data_read = malloc(regions->block_size);
 
  /* Calculate the offset at which the block lives */
  test_offset = (regions->offset + (block * regions->block_size));

  printf("\n -Starting Flash Test.\n");
 
  printf(" -Testing \"alt_write_flash\" and \"alt_read_flash\".\n");
  /* Fill buffer with incrementing values */
  for(i=0; i < regions->block_size; i++)
    *(data_written + i) = i;

  /* Write the buffer to flash block */
  ret_code = alt_write_flash(fd, test_offset, data_written,regions->block_size);
  if (!ret_code)
  {
    /* Read flash block into read buffer */
    ret_code = alt_read_flash(fd, test_offset, data_read, regions->block_size);
    if(!ret_code)
    {
      /* See if they match */
      if (memcmp(data_written, data_read, regions->block_size))
      {
        printf("    pass 1 - FAILED.\n");
        *error++;
      }
      else
        printf("    pass 1 - passed.\n");
    }
 
    /* Now fill the buffer with decrementing values (invert the incrementing ones) */
    for(i=0; i < regions->block_size; i++)
      *(data_written + i) = ~((alt_u8)(i));
 
    /* Write the buffer to flash block */
    ret_code = alt_write_flash(fd, test_offset, data_written, regions->block_size);
    if (!ret_code)
    {
      /* Read flash block into read buffer */
      ret_code = alt_read_flash(fd, test_offset, data_read, regions->block_size);
      if(!ret_code)
      {
        /* See if they match */
        if (memcmp(data_written, data_read, regions->block_size))
        {
          printf("    pass 2 - FAILED.\n");
          *error++;
        }
        else
          printf("    pass 2 - passed.\n");
      }
    }
    if (*error)
      ret_code = 1;
  }

  /* Free up the buffers we allocated */
  free(data_written);
  free(data_read);
  
  return ret_code;
}
Ejemplo n.º 5
0
/*
 * generate_and_store_mac_addr()
 * 
 * This routine is called when, upon program initialization, we discover
 * that there is no valid network settings (including MAC address) programmed
 * into flash memory at the last flash sector.  If it is not safe to use the 
 * contents of this last sector of flash, the user is prompted to
 * enter the serial number at the console.  A MAC address is then
 * generated using 0xFF followed by the last 2 bytes of the serial number 
 * appended to Altera's Vendor ID, an assigned MAC address range with the first
 * 3 bytes of 00:07:ED.  For example, if the Nios Development Board serial 
 * number is 040800017, the corresponding ethernet number generated will be
 * 00:07:ED:FF:8F:11.
 * 
 * It should be noted that this number, while unique, will likely differ from
 * the also unique (but now lost forever) MAC address programmed into the 
 * development board on the production line.
 * 
 * As we are erasing the entire flash sector, we'll re-program it with not
 * only the MAC address, but static IP, subnet, gateway, and "Use DHCP" 
 * sections. These fail-safe static settings are compatible with previous
 * Nios Ethernet designs, and allow the "factory-safe" design to behave 
 * as expected if the last flash sector is erased.
 */
error_t generate_and_store_mac_addr()
{
    error_t error = -1;
    alt_u32 ser_num = 0;
    char flash_content[32];
    alt_flash_fd* flash_handle;
    
    printf("Can't read the MAC address from your board (this probably means\n");
    printf("that your flash was erased). We will assign you a MAC address and\n");
    printf("static network settings\n\n");
    
    ser_num = get_serial_number();
  
    if (ser_num)
    {
        /* This says the image is safe */
        flash_content[0] = 0xfe;
        flash_content[1] = 0x5a;
        flash_content[2] = 0x0;
        flash_content[3] = 0x0;
        
        /* This is the Altera Vendor ID */
        flash_content[4] = 0x0;
        flash_content[5] = 0x7;
        flash_content[6] = 0xed;
        
        /* Reserverd Board identifier for erase boards */
        flash_content[7] = 0xFF;
        flash_content[8] = (ser_num & 0xff00) >> 8;
        flash_content[9] = ser_num & 0xff;
        
        /* Then comes a 16-bit "flags" field */
        flash_content[10] = 0xFF;
        flash_content[11] = 0xFF;
        
        /* Then comes the static IP address */
        flash_content[12] = IPADDR0;
        flash_content[13] = IPADDR1;
        flash_content[14] = IPADDR2;
        flash_content[15] = IPADDR3;
        
        /* Then comes the static nameserver address */
        flash_content[16] = 0xFF;
        flash_content[17] = 0xFF;
        flash_content[18] = 0xFF;
        flash_content[19] = 0xFF;
        
        /* Then comes the static subnet mask */
        flash_content[20] = MSKADDR0;
        flash_content[21] = MSKADDR1;
        flash_content[22] = MSKADDR2;
        flash_content[23] = MSKADDR3;
        
        /* Then comes the static gateway address */
        flash_content[24] = GWADDR0;
        flash_content[25] = GWADDR1;
        flash_content[26] = GWADDR2;
        flash_content[27] = GWADDR3;
        
        /* And finally whether to use DHCP - set all bits to be safe */
        flash_content[28] = 0xFF;
        flash_content[29] = 0xFF;
        flash_content[30] = 0xFF;
        flash_content[31] = 0xFF;
#if 0      
        /* Write the MAC address to flash */
        flash_handle = alt_flash_open_dev(EXT_FLASH_NAME);
        if (flash_handle)
        {
            alt_write_flash(flash_handle,
                            last_flash_sector_offset,
                            flash_content,
                            32);
            alt_flash_close_dev(flash_handle);
            error = 0;
        }
#endif
    }

    return error;    
}