Ejemplo n.º 1
0
extern uint32_t EFC_PerformCommand( Efc* efc, uint32_t dwCommand, uint32_t dwArgument, uint32_t dwUseIAP )
{
    if ( dwUseIAP != 0 )
    {
        /* Pointer on IAP function in ROM */
        static uint32_t (*IAP_PerformCommand)( uint32_t, uint32_t ) ;

        IAP_PerformCommand = (uint32_t (*)( uint32_t, uint32_t )) *((uint32_t*)CHIP_FLASH_IAP_ADDRESS ) ;
        IAP_PerformCommand( 0, EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ) ;

        return (efc->EEFC_FSR & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)) ;
    }
    else
    {
        uint32_t dwStatus ;

        efc->EEFC_FCR = EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ;
        do
        {
            dwStatus = efc->EEFC_FSR ;
        }
        while ( (dwStatus & EEFC_FSR_FRDY) != EEFC_FSR_FRDY ) ;

        return ( dwStatus & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE) ) ;
    }
}
Ejemplo n.º 2
0
void banzai() {
	// Disable all interrupts
	__disable_irq();

	// Set bootflag to run SAM-BA bootloader at restart
	const int EEFC_FCMD_CGPB = 0x0C;
	const int EEFC_KEY = 0x5A;
	while (EFC0->EEFC_FSR & EEFC_FSR_FRDY == 0);
	EFC0->EEFC_FCR =
		EEFC_FCR_FCMD(EEFC_FCMD_CGPB) |
		EEFC_FCR_FARG(1) |
		EEFC_FCR_FKEY(EEFC_KEY);
	while (EFC0->EEFC_FSR & EEFC_FSR_FRDY == 0);

	// From here flash memory is no more available.

	// Memory swap needs some time to stabilize
	for (uint32_t i=0; i<1000000; i++)
		// force compiler to not optimize this
		__asm__ __volatile__("");

	// BANZAIIIIIII!!!
	const int RSTC_KEY = 0xA5;
	RSTC->RSTC_CR =
		RSTC_CR_KEY(RSTC_KEY) |
		RSTC_CR_PROCRST |
		RSTC_CR_PERRST;

	while (true);
}
Ejemplo n.º 3
0
/**
 * \brief Starts the executing the given command on the EEFC and returns as soon as the command is started.
 *
 * \note It does NOT set the FMCN field automatically.
 * \param efc  Pointer to a Efc instance
 * \param command  Command to execute.
 * \param argument  Command argument (should be 0 if not used).
 */
extern void EFC_StartCommand( Efc* efc, uint32_t dwCommand, uint32_t dwArgument )
{
    /* Check command & argument */
    switch ( dwCommand )
    {
        case EFC_FCMD_WP:
        case EFC_FCMD_WPL:
        case EFC_FCMD_EWP:
        case EFC_FCMD_EWPL:
        case EFC_FCMD_SLB:
        case EFC_FCMD_CLB:
            assert( dwArgument < IFLASH_NB_OF_PAGES ) ;
        break ;

        case EFC_FCMD_SFB:
        case EFC_FCMD_CFB:
            assert( dwArgument < 2 ) ;
        break;

        case EFC_FCMD_GETD:
        case EFC_FCMD_EA:
        case EFC_FCMD_GLB:
        case EFC_FCMD_GFB:
        case EFC_FCMD_STUI:
            assert( dwArgument == 0 ) ;
        break;

        default: assert( 0 ) ;
    }

    /* Start command Embedded flash */
    assert( (efc->EEFC_FSR & EEFC_FMR_FRDY) == EEFC_FMR_FRDY ) ;
    efc->EEFC_FCR = EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ;
}
Ejemplo n.º 4
0
void banzai() {
	// Disable all interrupts
	__disable_irq();

	// Set bootflag to run SAM-BA bootloader at restart
	const int EEFC_FCMD_CGPB = 0x0C;
	const int EEFC_KEY = 0x5A;
	while ((EFC0->EEFC_FSR & EEFC_FSR_FRDY) == 0);
	EFC0->EEFC_FCR =
		EEFC_FCR_FCMD(EEFC_FCMD_CGPB) |
		EEFC_FCR_FARG(1) |
		EEFC_FCR_FKEY(EEFC_KEY);
	while ((EFC0->EEFC_FSR & EEFC_FSR_FRDY) == 0);

	// From here flash memory is no more available.

	// BANZAIIIIIII!!!
	const int RSTC_KEY = 0xA5;
	RSTC->RSTC_CR =
		RSTC_CR_KEY(RSTC_KEY) |
		RSTC_CR_PROCRST |
		RSTC_CR_PERRST;

	while (true);
}
Ejemplo n.º 5
0
/**
 * \brief Perform the given command and wait until its completion (or an error).
 *
 * \note Unique ID commands are not supported, use efc_read_unique_id.
 *
 * \param p_efc Pointer to an EFC instance.
 * \param ul_command Command to perform.
 * \param ul_argument Optional command argument.
 *
 * \note This function will automatically choose to use IAP function.
 *
 * \return 0 if successful, otherwise returns an error code.
 */
uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
		uint32_t ul_argument)
{
	// Unique ID commands are not supported.
	if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
		return EFC_RC_NOT_SUPPORT;
	}

#if (SAM3XA_SERIES || SAM3U4)
	// Use IAP function with 2 parameters in ROM.
	static uint32_t(*iap_perform_command) (uint32_t, uint32_t);
	uint32_t ul_efc_nb = (p_efc == EFC0) ? 0 : 1;

	iap_perform_command =
			(uint32_t(*)(uint32_t, uint32_t))
			*((uint32_t *) CHIP_FLASH_IAP_ADDRESS);
	iap_perform_command(ul_efc_nb,
			EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(ul_argument) |
			EEFC_FCR_FCMD(ul_command));
	return (p_efc->EEFC_FSR & EEFC_ERROR_FLAGS);
#elif (SAM3N_SERIES || SAM3S_SERIES || SAM4S_SERIES || SAM3U_SERIES)
	// Use IAP function with 2 parameter in ROM.
	static uint32_t(*iap_perform_command) (uint32_t, uint32_t);

	iap_perform_command =
			(uint32_t(*)(uint32_t, uint32_t))
			*((uint32_t *) CHIP_FLASH_IAP_ADDRESS);
#if SAM4S_SERIES
    uint32_t ul_efc_nb = (p_efc == EFC0) ? 0 : 1;
	iap_perform_command(ul_efc_nb,
			EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(ul_argument) |
			EEFC_FCR_FCMD(ul_command));
#else
	iap_perform_command(0,
			EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(ul_argument) |
			EEFC_FCR_FCMD(ul_command));
#endif
	return (p_efc->EEFC_FSR & EEFC_ERROR_FLAGS);
#else
	// Use RAM Function.
	return efc_perform_fcr(p_efc,
			EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(ul_argument) |
			EEFC_FCR_FCMD(ul_command));

#endif
}
Ejemplo n.º 6
0
Archivo: efc.c Proyecto: lclc/mcu
/**
 * \brief Perform the given command and wait until its completion (or an error).
 *
 * \note Unique ID commands are not supported, use efc_perform_read_sequence.
 *
 * \param p_efc Pointer to an EFC instance.
 * \param ul_command Command to perform.
 * \param ul_argument Optional command argument.
 *
 * \note This function will automatically choose to use IAP function.
 *
 * \return 0 if successful, otherwise returns an error code.
 */
uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
		uint32_t ul_argument)
{
	/* Unique ID commands are not supported. */
	if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
		return EFC_RC_NOT_SUPPORT;
	}

	/* Use RAM Function. */
	return efc_perform_fcr(p_efc,
			EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(ul_argument) |
			EEFC_FCR_FCMD(ul_command));
}
Ejemplo n.º 7
0
/**
 * \brief Perform the given command and wait until its completion (or an error).
 *
 * \note Unique ID commands are not supported, use efc_perform_read_sequence.
 *
 * \param p_efc Pointer to an EFC instance.
 * \param ul_command Command to perform.
 * \param ul_argument Optional command argument.
 *
 * \note This function will automatically choose to use IAP function.
 *
 * \return 0 if successful, otherwise returns an error code.
 */
uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
		uint32_t ul_argument)
{
	uint32_t result;
	irqflags_t flags;

	/* Unique ID commands are not supported. */
	if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
		return EFC_RC_NOT_SUPPORT;
	}

	flags = cpu_irq_save();
	/* Use RAM Function. */
	result = efc_perform_fcr(p_efc,
			EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(ul_argument) |
			EEFC_FCR_FCMD(ul_command));
	cpu_irq_restore(flags);
	return result;
}
Ejemplo n.º 8
0
uint32_t efc_perform_read_sequence(Efc *p_efc,
		uint32_t ul_cmd_st, uint32_t ul_cmd_sp,
		uint32_t *p_ul_buf, uint32_t ul_size)
{
	volatile uint32_t ul_status;
	uint32_t ul_cnt;

#if (SAM3U4 || SAM3XA_SERIES /*|| SAM4SD16 || SAM4SD32*/)
	uint32_t *p_ul_data =
			(uint32_t *) ((p_efc == EFC0) ?
			READ_BUFF_ADDR0 : READ_BUFF_ADDR1);
#elif (SAM3S_SERIES || SAM4S_SERIES || SAM3N_SERIES || SAM3U_SERIES)
	uint32_t *p_ul_data = (uint32_t *) READ_BUFF_ADDR;
#else
	return EFC_RC_NOT_SUPPORT;
#endif

	if (p_ul_buf == NULL) {
		return EFC_RC_INVALID;
	}

	p_efc->EEFC_FMR |= (0x1u << 16);

	/* Send the Start Read command */
#if SAM4S_SERIES
	p_efc->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(0)
			| EEFC_FCR_FCMD(ul_cmd_st);
#else
    p_efc->EEFC_FCR = EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(0)
			| EEFC_FCR_FCMD(ul_cmd_st);
#endif
	/* Wait for the FRDY bit in the Flash Programming Status Register
	 * (EEFC_FSR) falls.
	 */
	do {
		ul_status = p_efc->EEFC_FSR;
	} while ((ul_status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY);

	/* The data is located in the first address of the Flash
	 * memory mapping.
	 */
	for (ul_cnt = 0; ul_cnt < ul_size; ul_cnt++) {
		p_ul_buf[ul_cnt] = p_ul_data[ul_cnt];
	}

	/* To stop the read mode */
	p_efc->EEFC_FCR =
#if SAM4S_SERIES
			EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(0) |
			EEFC_FCR_FCMD(ul_cmd_sp);
#else
			EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(0) |
			EEFC_FCR_FCMD(ul_cmd_sp);
#endif
	/* Wait for the FRDY bit in the Flash Programming Status Register (EEFC_FSR)
	 * rises.
	 */
	do {
		ul_status = p_efc->EEFC_FSR;
	} while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);

	p_efc->EEFC_FMR &= ~(0x1u << 16);

	return EFC_RC_OK;
}