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 ); }
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; }
/** * \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; }
/** * 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); }
/** * \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); }
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; }
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); }
/** * \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; }
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; }