예제 #1
0
void vInitialiseTimerForIntQueueTest( void )
{
	/* Enable the TC clocks. */
	pmc_enable_peripheral( ID_TC0 );
	pmc_enable_peripheral( ID_TC1 );

	/* Configure TC0 channel 0 for a tmrTIMER_0_FREQUENCY frequency and trigger
	on RC compare. */
	tc_trigger_on_freq( TC0, tmrTC0_CHANNEL_0, tmrTIMER_0_FREQUENCY );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_IER = TC_IER_CPCS;

	/* Configure TC0 channel 1 for a tmrTIMER_1_FREQUENCY frequency and trigger
	on RC compare. */
	tc_trigger_on_freq( TC0, tmrTC0_CHANNEL_1, tmrTIMER_1_FREQUENCY );
	TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_IER = TC_IER_CPCS;

	/* Configure TC1 channel 0 tmrTIMER_2_FREQUENCY frequency and trigger on
	RC compare. */
	tc_trigger_on_freq( TC1, tmrTC1_CHANNEL_0, tmrTIMER_2_FREQUENCY );
	TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_IER = TC_IER_CPCS;

	/* Enable interrupts and start the timers. */
	aic_configure( ID_TC0, tmrLOWER_PRIORITY );
	aic_set_source_vector( ID_TC0, prvTC0_Handler );
	aic_configure( ID_TC1, tmrHIGHER_PRIORITY );
	aic_set_source_vector( ID_TC1, prvTC1_Handler );
	aic_enable( ID_TC0 );
	aic_enable( ID_TC1 );
	tc_start( TC0, tmrTC0_CHANNEL_0 );
	tc_start( TC0, tmrTC0_CHANNEL_1 );
	tc_start( TC1, tmrTC1_CHANNEL_0 );
}
예제 #2
0
uint32_t xdmad_prepare_channel(struct _xdmad_channel *channel)
{
	Xdmac *xdmac = channel->xdmac;

	if (channel->state == XDMAD_STATE_FREE)
		return XDMAD_ERROR;
	else if (channel->state == XDMAD_STATE_STARTED)
		return XDMAD_BUSY;

	/* Clear status */
	xdmac_get_global_channel_status(xdmac);
	xdmac_get_global_isr(xdmac);

	/* Enable clock of the DMA peripheral */
	pmc_enable_peripheral(xdmac_get_periph_id(xdmac));

	/* Clear status */
	xdmac_get_channel_isr(xdmac, channel->id);

	/* Disables XDMAC interrupt for the given channel */
	xdmac_disable_global_it(xdmac, -1);
	xdmac_disable_channel_it(xdmac, channel->id, -1);

	/* Disable the given dma channel */
	xdmac_disable_channel(xdmac, channel->id);
	xdmac_set_src_addr(xdmac, channel->id, 0);
	xdmac_set_dest_addr(xdmac, channel->id, 0);
	xdmac_set_block_control(xdmac, channel->id, 0);
	xdmac_set_channel_config(xdmac, channel->id, XDMAC_CC_PROT_UNSEC);
	xdmac_set_descriptor_addr(xdmac, channel->id, 0, 0);
	xdmac_set_descriptor_control(xdmac, channel->id, 0);

	return XDMAD_OK;
}
예제 #3
0
파일: console.c 프로젝트: wugsh/wgs
/**
* \brief Configures a CONSOLE peripheral with the specified parameters.
*
* \param baudrate  Baudrate at which the CONSOLE should operate (in Hz).
*/
void console_configure(uint32_t baudrate)
{
	/* Configure PIO */
	pio_configure(pinsConsole, ARRAY_SIZE(pinsConsole));

	pmc_enable_peripheral(CONSOLE_ID);

	uint32_t mode;
#if CONSOLE_DRIVER != DRV_DBGU
	mode = US_MR_CHMODE_NORMAL | US_MR_PAR_NO | US_MR_CHRL_8_BIT;
#else
	mode = US_MR_CHMODE_NORMAL | US_MR_PAR_NO;
#endif

#if CONSOLE_DRIVER == DRV_UART
	uint32_t mr;
	mr = mode & US_MR_FILTER ? UART_MR_FILTER_ENABLED
	    : UART_MR_FILTER_DISABLED;
	mr |= UART_MR_PAR((mode & US_MR_PAR_Msk) >> US_MR_PAR_Pos);
	if ((mode & US_MR_USCLKS_Msk) == US_MR_USCLKS_PMC_PCK)
		mr |= UART_MR_BRSRCCK_PMC_PCK;
	else
		mr |= UART_MR_BRSRCCK_PERIPH_CLK;
	mr |= UART_MR_CHMODE((mode & US_MR_CHMODE_Msk) >> US_MR_CHMODE_Pos);
	mode = mr;
#endif

	/* Initialize driver to use */
	console.init(console.addr, mode, baudrate);

	/* Finally */
	_bConsoleIsInitialized = 1;
}
예제 #4
0
/**
 *  Configure Timer Counter 0 to generate an interrupt every 250ms.
 */
static void _configure_tc(void)
{
	/** Enable peripheral clock. */
	pmc_enable_peripheral(ID_TC0);

	/* Put the source vector */
	aic_set_source_vector(ID_TC0, _tc_handler);

	/** Configure TC for a 50Hz frequency and trigger on RC compare. */
	tc_trigger_on_freq(TC0, TC_CHANNEL, TC_FREQ);

	/* Configure and enable interrupt on RC compare */
	tc_enable_it(TC0, TC_CHANNEL, TC_IER_CPCS);
	aic_enable(ID_TC0);
}
예제 #5
0
/**
 *  \brief getting-started Application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint32_t* p;
	uint8_t i;

	/* Output example information */
	console_example_info("AESB Example");

	/* Enable peripheral clock */
	pmc_enable_peripheral(ID_AESB);
	/* Perform a software-triggered hardware reset of the AES interface */
	aesb_swrst();

	printf("-I- Configure AESB in automatic bridge mode: AES CTR selected\n\r");
	/* Enable AESB automatic bridge mode */
	aesb_configure( AESB_MR_AAHB
					| AESB_MR_DUALBUFF_ACTIVE
					| AESB_MR_PROCDLY(0)
					| AESB_MR_SMOD_AUTO_START
					| AESB_MR_OPMOD_CTR
					| AESB_MR_CKEY_PASSWD
					);
	/* The Automatic Bridge mode, when the AESB block is connected between the system bus 
	and a DDR port, provides automatic encryption/decryption to/from a DDR port without 
	any action on the part of the user. */
	printf("-I- Transfer data to address of AESB IP scope, the data is encrypted automatically\n\r");
	p = (uint32_t *)(DDR_AES_CS_ADDR + DDR_RESERVED_LEN);
	for (i = 0; i < 64; i++)
		*p++ = i;
	cache_clean_region((void*)(DDR_AES_CS_ADDR + DDR_RESERVED_LEN), 64);
	
	printf("-I- Read data from address of AESB IP scope\r\n");

	p = (uint32_t *)(DDR_AES_CS_ADDR + DDR_RESERVED_LEN);
	for (i = 0; i < 64; i++)
		printf("%x ",(unsigned)*p++);
	printf("\r\n-I- As expected, it automatically decrypts the data read from the target slave before putting it on the system bus\r\n");
	
	printf("\r\n-I- Read data from address outside of AESB IP scope. This test is expeted to fail.\r\n");

	p = (uint32_t*)(DDR_CS_ADDR + DDR_RESERVED_LEN);
	for (i = 0; i < 64; i++)
		printf("%x ", (unsigned)*p++);
	printf("\r\n-I- As expected, data cannot be decrypted from address outside of AESB IP scope\r\n");

	while(1);
}
예제 #6
0
void qspi_initialize(Qspi *qspi)
{
	pmc_enable_peripheral(get_qspi_id_from_addr(qspi));

	/* Disable write protection */
	qspi->QSPI_WPMR = QSPI_WPMR_WPKEY_PASSWD;

	/* Reset */
	qspi->QSPI_CR = QSPI_CR_SWRST;

	/* Configure */
	qspi->QSPI_MR = QSPI_MR_SMM_MEMORY;
	qspi->QSPI_SCR = 0;

	/* Enable */
	qspi->QSPI_CR = QSPI_CR_QSPIEN;
}
예제 #7
0
bool gmac_configure(Gmac* gmac)
{
	pmc_enable_peripheral(get_gmac_id_from_addr(gmac));

	/* Disable TX & RX and more */
	gmac_set_network_control_register(gmac, 0);
	gmac_set_network_config_register(gmac, GMAC_NCFGR_DBW_DBW32);

	/* Disable interrupts */
	gmac_disable_it(gmac, 0, ~0u);
#ifdef CONFIG_HAVE_GMAC_QUEUES
	gmac_disable_it(gmac, 1, ~0u);
	gmac_disable_it(gmac, 2, ~0u);
#endif

	/* Clear statistics */
	gmac_clear_statistics(gmac);

	/* Clear all status bits in the receive status register. */
	gmac_clear_rx_status(gmac, GMAC_RSR_RXOVR | GMAC_RSR_REC |
			GMAC_RSR_BNA | GMAC_RSR_HNO);

	/* Clear all status bits in the transmit status register */
	gmac_clear_tx_status(gmac, GMAC_TSR_UBR | GMAC_TSR_COL |
			GMAC_TSR_RLE | GMAC_TSR_TXGO | GMAC_TSR_TFC |
			GMAC_TSR_TXCOMP | GMAC_TSR_UND | GMAC_TSR_HRESP);

	/* Clear interrupts */
	gmac_get_it_status(gmac, 0);
#ifdef CONFIG_HAVE_GMAC_QUEUES
	gmac_get_it_status(gmac, 1);
	gmac_get_it_status(gmac, 2);
#endif

	return _gmac_configure_mdc_clock(gmac);
}
예제 #8
0
/**
 * \brief Configures a list of Pin instances, each of which can either
 * hold a single pin or a group of pins, depending on the mask value;
 * all pins are configured by this function. The size of the array
 * must also be provided and is easily computed using ARRAY_SIZE
 * whenever its length is not known in advance.
 *
 * \param list  Pointer to a list of _pin instances.
 * \param size  Size of the _pin list (calculated using PIN_LISTSIZE).
 *
 * \return 1 if the pins have been configured properly; otherwise 0.
 */
uint8_t pio_configure(const struct _pin *pin_list, uint32_t size)
{
	union _pio_cfg cfg;
	PioIo_group* pioiog;

	/* Configure pins */
	while (size--)
	{
		/* Enable the PIO group if needed */
		uint32_t periph_id = _pio_group_to_id(pin_list->group);

		assert(pin_list->group < PIO_GROUP_LENGTH);
		cfg.uint32_value = 0;
		pioiog = (PioIo_group*) _pio_configure_pins(pin_list, periph_id);

		if ( pin_list->attribute != PIO_DEFAULT) {
			cfg.bitfield.puen = (pin_list->attribute & PIO_PULLUP)? 1:0;
			cfg.bitfield.pden = (pin_list->attribute & PIO_PULLDOWN)? 1:0;
			cfg.bitfield.ifen = (pin_list->attribute & PIO_DEGLITCH)? 1:0;
			cfg.bitfield.ifscen = (pin_list->attribute & PIO_DEBOUNCE)? 1:0;
			cfg.bitfield.opd = (pin_list->attribute & PIO_OPENDRAIN)? 1:0;
			cfg.bitfield.schmitt =(pin_list->attribute & PIO_TRIGGER_DIS)? 1:0;

			switch (pin_list->attribute & PIO_DRVSTR_Msk) {
			case PIO_DRVSTR_HI:
				cfg.bitfield.drvstr = PIO_CFGR_DRVSTR_HI >> PIO_CFGR_DRVSTR_Pos;
				break;
			case PIO_DRVSTR_ME:
				cfg.bitfield.drvstr = PIO_CFGR_DRVSTR_ME >> PIO_CFGR_DRVSTR_Pos;
				break;
			case PIO_DRVSTR_LO:
			default:
				cfg.bitfield.drvstr = PIO_CFGR_DRVSTR_LO >> PIO_CFGR_DRVSTR_Pos;
				break;
			}

			switch (pin_list->attribute & PIO_EVTSEL_Msk) {
			case PIO_IT_HIGH_LEVEL:
				cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_HIGH >> PIO_CFGR_EVTSEL_Pos;
				break;
			case PIO_IT_LOW_LEVEL:
				cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_LOW >> PIO_CFGR_EVTSEL_Pos;
				break;
			case PIO_IT_BOTH_EDGE:
				cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_BOTH >> PIO_CFGR_EVTSEL_Pos;
				break;
			case PIO_IT_RISE_EDGE:
				cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_RISING >> PIO_CFGR_EVTSEL_Pos;
				break;
			case PIO_IT_FALL_EDGE:
			default:
				cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_FALLING >> PIO_CFGR_EVTSEL_Pos;
				break;
			}
		}

		switch (pin_list->type){

		case PIO_PERIPH_A:
			cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_A >> PIO_CFGR_FUNC_Pos;
			break;
		case PIO_PERIPH_B:
			cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_B >> PIO_CFGR_FUNC_Pos;
			break;
		case PIO_PERIPH_C:
			cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_C >> PIO_CFGR_FUNC_Pos;
			break;
		case PIO_PERIPH_D:
			cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_D >> PIO_CFGR_FUNC_Pos;
			break;
		case PIO_PERIPH_E:
			cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_E >> PIO_CFGR_FUNC_Pos;
			break;
		case PIO_PERIPH_F:
			cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_F >> PIO_CFGR_FUNC_Pos;
			break;
		case PIO_GENERIC:
		case PIO_INPUT:
			cfg.bitfield.dir = 0;
			break;

		case PIO_OUTPUT_0:
			cfg.bitfield.dir = 1;
			pio_clear(pin_list);
			break;

		case PIO_OUTPUT_1:
			cfg.bitfield.dir = 1;
			pio_set(pin_list);
			break;

		default:
		case PIO_PERIPH_G:
			return 0;
		}

		pioiog->PIO_MSKR = pin_list->mask;
		pioiog->PIO_CFGR = cfg.uint32_value;
		pmc_enable_peripheral(periph_id);

		++pin_list;
	}
예제 #9
0
static uint32_t handle_cmd_initialize(uint32_t cmd, uint32_t *mailbox)
{
	union initialize_mailbox *mbx = (union initialize_mailbox*)mailbox;
	uint32_t instance = mbx->in.parameters[0];
	uint32_t boot_partition = mbx->in.parameters[1];
	uint32_t bus_width = mbx->in.parameters[2];
	uint32_t supported_voltages = mbx->in.parameters[3];
	const struct sdmmc_pin_definition* instance_def;
	uint32_t max_bus_width, sdmmc_id, caps0;
	uint8_t rc, card_type;

	assert(cmd == APPLET_CMD_INITIALIZE);

	applet_set_init_params(mbx->in.comm_type, mbx->in.trace_level);
	initialized = false;

	trace_info_wp("\r\nApplet 'SD/MMC' from "
			"softpack " SOFTPACK_VERSION ".\r\n");

	if (bus_width != 0 && bus_width != 1 &&
			bus_width != 4 && bus_width != 8) {
		trace_error_wp("Invalid configuration: Unsupported bus width %u\r\n",
			(unsigned)bus_width);
		return APPLET_FAIL;
	}

	if (!supported_voltages || (supported_voltages & ~SUPPORTED_VOLTAGE_MASK)) {
		trace_error_wp("Invalid supported voltages value: 0x%x\r\n",
			(unsigned)supported_voltages);
		return APPLET_FAIL;
	}

	instance_def = find_instance(instance);
	if (!instance_def) {
		trace_error_wp("Invalid configuration: SDMMC%u\r\n",
			(unsigned)instance);
		return APPLET_FAIL;
	}

	max_bus_width = get_max_bus_width(instance_def);
	if (!bus_width) {
		bus_width = max_bus_width;
	} else if (bus_width > max_bus_width) {
		trace_error_wp("Invalid configuration: SDMMC%u Bus Width %u\r\n",
			(unsigned)instance, (unsigned)bus_width);
		return APPLET_FAIL;
	}

	if (boot_partition > 2) {
		trace_error_wp("Invalid configuration: Unknown partition %u\r\n",
			(unsigned)boot_partition);
		return APPLET_FAIL;
	}

	trace_info_wp("Initializing SDMMC%u", (unsigned)instance);
	if (boot_partition)
		trace_info_wp(", boot partition %u",
				(unsigned)boot_partition);
	else
		trace_info_wp(", user partition");
	if (bus_width == 1)
		trace_info_wp(", 1-bit");
	else if (bus_width == 4)
		trace_info_wp(", 4-bit");
	else if (bus_width == 8)
		trace_info_wp(", 8-bit");
	trace_info_wp(", %s",
			get_supported_voltage_string(supported_voltages));
	trace_info_wp("\r\n");

	/* Configure PIO */
	configure_instance_pio(instance_def, bus_width, supported_voltages);

	/* The SDMMC peripherals are clocked by their Peripheral Clock, the
	 * Master Clock, and a Generated Clock (at least on SAMA5D2x).
	 * Configure GCLKx = <PLLA clock> divided by 1
	 * As of writing, the PLLA clock runs at 498 MHz */
	sdmmc_id = get_sdmmc_id_from_addr(instance_def->addr);
	pmc_configure_gck(sdmmc_id, PMC_PCR_GCKCSS_PLLA_CLK, 1 - 1);
	pmc_enable_gck(sdmmc_id);
	pmc_enable_peripheral(sdmmc_id);

	// set SDMMC controller capabilities
	caps0 = SDMMC_CA0R_SLTYPE_EMBEDDED;
	if (bus_width == 8)
		caps0 |= SDMMC_CA0R_ED8SUP;
	if (supported_voltages & SUPPORTED_VOLTAGE_18V)
		caps0 |= SDMMC_CA0R_V18VSUP;
	if (supported_voltages & SUPPORTED_VOLTAGE_30V)
		caps0 |= SDMMC_CA0R_V30VSUP;
	if (supported_voltages & SUPPORTED_VOLTAGE_33V)
		caps0 |= SDMMC_CA0R_V33VSUP;
	sdmmc_set_capabilities(instance_def->addr,
			caps0, CAPS0_MASK, 0, 0);

	sdmmc_initialize(&drv, instance_def->addr, sdmmc_id,
			TIMER0_MODULE, TIMER0_CHANNEL, NULL, 0);

	SDD_InitializeSdmmcMode(&lib, &drv, 0);
	if (SD_GetStatus(&lib) == SDMMC_NOT_SUPPORTED) {
		trace_error_wp("Device not detected.\n\r");
		return APPLET_FAIL;
	}

	rc = SD_Init(&lib);
	if (rc != SDMMC_OK) {
		trace_error_wp("SD/MMC device initialization failed: %d\n\r", rc);
		return APPLET_FAIL;
	}

	card_type = SD_GetCardType(&lib);
	if (!(card_type & CARD_TYPE_bmSDMMC)) {
		trace_error_wp("Invalid card type: only SD/MMC is supported\n\r");
		return APPLET_FAIL;
	}

	SD_DumpStatus(&lib);

	if (boot_partition) {
		/* check that card is MMC */
		if (!(card_type & CARD_TYPE_bmMMC)) {
			trace_error_wp("Invalid card type: boot partition in only supported on MMC\n\r");
			return APPLET_FAIL;
		}

		/* get and check boot partition size */
		mem_size = MMC_EXT_BOOT_SIZE_MULTI(lib.EXT) * (128 * 1024 / BLOCK_SIZE);
		if (mem_size == 0) {
			trace_error_wp("No boot partition available\n\r");
			return APPLET_FAIL;
		}

		/* configure boot partition */
		mmc_configure_partition(&lib, EMMC_BOOT_PARTITION_ACCESS(boot_partition) |
		                              EMMC_BOOT_PARTITION_ENABLE(boot_partition) |
		                              EMMC_BOOT_ACK);
		mmc_configure_boot_bus(&lib, 0);
	} else {
		mem_size = SD_GetTotalSizeKB(&lib) * 1024 / BLOCK_SIZE;
	}

	buffer = applet_buffer;
	buffer_size = applet_buffer_size & ~(BLOCK_SIZE - 1);
	if (buffer_size == 0) {
		trace_info_wp("Not enough memory for buffer\r\n");
		return APPLET_FAIL;
	}

	mbx->out.buf_addr = (uint32_t)buffer;
	mbx->out.buf_size = buffer_size;
	mbx->out.page_size = BLOCK_SIZE;
	mbx->out.erase_support = 0;
	mbx->out.mem_size = mem_size;

	trace_info_wp("SD/MMC device initialization successful\n\r");
	trace_info_wp("Buffer Address: 0x%lx\r\n", mbx->out.buf_addr);
	trace_info_wp("Buffer Size: %ld bytes\r\n", mbx->out.buf_size);
	trace_info_wp("Page Size: %ld bytes\r\n", mbx->out.page_size);
	trace_info_wp("Memory Size: %ld pages\r\n", mbx->out.mem_size);

	initialized = true;
	return APPLET_SUCCESS;
}