void cyg_hal_sh_pcic_pci_cfg_write_word (cyg_uint32 bus, cyg_uint32 devfn, cyg_uint32 offset, cyg_uint16 data) { cyg_uint32 config_dword, shift; HAL_WRITE_UINT32(CYGARC_REG_PCIC_PAR, CYGARC_REG_PCIC_PAR_ENABLE | (bus << CYGARC_REG_PCIC_PAR_BUSNO_shift) | (devfn << CYGARC_REG_PCIC_PAR_FUNC_shift) | (offset & ~3)); HAL_READ_UINT32(CYGARC_REG_PCIC_PDR, config_dword); shift = (offset & 3) * 8; config_dword &= ~(0xffff << shift); config_dword |= (data << shift); HAL_WRITE_UINT32(CYGARC_REG_PCIC_PAR, CYGARC_REG_PCIC_PAR_ENABLE | (bus << CYGARC_REG_PCIC_PAR_BUSNO_shift) | (devfn << CYGARC_REG_PCIC_PAR_FUNC_shift) | (offset & ~3)); HAL_WRITE_UINT32(CYGARC_REG_PCIC_PDR, config_dword); }
static void spi_at91_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) { cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *) data; cyg_uint32 stat; // Read the status register and // check for transfer completion HAL_READ_UINT32(spi_bus->base+AT91_SPI_SR, stat); if((stat & AT91_SPI_SR_ENDRX) && (stat & AT91_SPI_SR_ENDTX)) { // Transfer ended spi_bus->transfer_end = true; cyg_drv_cond_signal(&spi_bus->transfer_cond); } else { // Transfer still in progress - unmask the SPI // int so we can get more SPI int events cyg_drv_interrupt_unmask(vector); } }
// in: // // sym_type Type of relocation to apply, // mem Address in memory to modify (relocate). // sym_value cyg_int32 cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value ) { cyg_int32 rel_offset, i; // PPC uses rela, so we have to add the addend. switch( sym_type ) { case R_PPC_ADDR16_HA: HAL_WRITE_UINT16( mem, _ha_( sym_value ) ); return 0; case R_PPC_ADDR16_HI: HAL_WRITE_UINT16( mem, _hi_( sym_value ) ); return 0; case R_PPC_ADDR16_LO: HAL_WRITE_UINT16( mem, _lo_( sym_value ) ); return 0; case R_PPC_REL24: // Now it is time to seek the destination address of the call. // We need to do something in case the user jumps more than 16MB. rel_offset = ( sym_value - mem ) & 0x03FFFFFC; HAL_READ_UINT32( mem, i ); i &= 0xFC000003; HAL_WRITE_UINT32( mem, rel_offset | i ); return 0; case R_PPC_REL32: HAL_WRITE_UINT32( mem, ( sym_value - mem ) ); return 0; case R_PPC_ADDR32: HAL_WRITE_UINT32( mem, sym_value ); return 0; default: ELFDEBUG( "FIXME: Unknown relocation value!!!\n" ); return -1; } }
static int hal_a2fxxx_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...) { channel_data_t* chan = (channel_data_t*)__ch_data; CYG_ADDRESS base = ((channel_data_t*)__ch_data)->base; int ret = 0; cyg_uint32 ier; va_list ap; CYGARC_HAL_SAVE_GP(); va_start(ap, __func); switch (__func) { case __COMMCTL_IRQ_ENABLE: chan->irq_state = 1; HAL_INTERRUPT_ACKNOWLEDGE( chan->isr_vector ); HAL_INTERRUPT_UNMASK( chan->isr_vector ); HAL_READ_UINT32(base + CYGHWR_HAL_A2FXXX_UART16550_IER, ier ); ier |= CYGHWR_HAL_A2FXXX_UART16550_IER_ERBFI; HAL_WRITE_UINT32(base + CYGHWR_HAL_A2FXXX_UART16550_IER, ier ); break; case __COMMCTL_IRQ_DISABLE: ret = chan->irq_state; chan->irq_state = 0; HAL_INTERRUPT_MASK( chan->isr_vector ); HAL_READ_UINT32(base + CYGHWR_HAL_A2FXXX_UART16550_IER, ier ); ier &= ~CYGHWR_HAL_A2FXXX_UART16550_IER_ERBFI; HAL_WRITE_UINT32(base + CYGHWR_HAL_A2FXXX_UART16550_IER, ier ); break; case __COMMCTL_DBG_ISR_VECTOR: ret = chan->isr_vector; break; case __COMMCTL_SET_TIMEOUT: { va_list ap; va_start(ap, __func); ret = chan->msec_timeout; chan->msec_timeout = va_arg(ap, cyg_uint32); va_end(ap); } case __COMMCTL_GETBAUD: ret = chan->baud_rate; break; case __COMMCTL_SETBAUD: chan->baud_rate = va_arg(ap, cyg_int32); // Should we verify this value here? hal_a2fxxx_uart_setbaud( base, chan->baud_rate ); ret = 0; break; default: break; } va_end(ap); CYGARC_HAL_RESTORE_GP(); return ret; }
/** * * Hardware initialization. * * @return none * *****************************************************************************/ void hal_hardware_init(void) { cyg_uint32 dw_i, dwCPUID; // -------- Ininializing GIC ------------------------------------------- // Connect GIC to CORE0 dwCPUID = 1; HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + XSCUGIC_DIST_EN_OFFSET, 0UL); // For the Shared Peripheral Interrupts INT_ID[MAX..32], set: // // 1. The trigger mode in the int_config register // Only write to the SPI interrupts, so start at 32 // for (dw_i = 32; dw_i < XSCUGIC_MAX_NUM_INTR_INPUTS; dw_i += 16) { // // Each INT_ID uses two bits, or 16 INT_ID per register // Set them all to be level sensitive, active HIGH. // HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + XSCUGIC_INT_CFG_OFFSET_CALC(dw_i), 0UL); } for (dw_i = 0; dw_i < XSCUGIC_MAX_NUM_INTR_INPUTS; dw_i += 4) { // // 2. The priority using int the priority_level register // The priority_level and spi_target registers use one byte per // INT_ID. // Write a default value that can be changed elsewhere. // HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + XSCUGIC_PRIORITY_OFFSET_CALC(dw_i), DEFAULT_PRIORITY); } for (dw_i = 32; dw_i < XSCUGIC_MAX_NUM_INTR_INPUTS; dw_i += 4) { // // 3. The CPU interface in the spi_target register // Only write to the SPI interrupts, so start at 32 // dwCPUID |= dwCPUID << 8; dwCPUID |= dwCPUID << 16; HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + XSCUGIC_SPI_TARGET_OFFSET_CALC(dw_i), dwCPUID); } for (dw_i = 0; dw_i < XSCUGIC_MAX_NUM_INTR_INPUTS; dw_i += 32) { // // 4. Enable the SPI using the enable_set register. Leave all // disabled for now. // HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + XSCUGIC_ENABLE_DISABLE_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, dw_i), 0xFFFFFFFFUL); } HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + XSCUGIC_DIST_EN_OFFSET, XSCUGIC_EN_INT_MASK); // // Program the priority mask of the CPU using the Priority mask register // HAL_WRITE_UINT32(XC7Z_SCUGIC_CPU_BASEADDR + XSCUGIC_CPU_PRIOR_OFFSET, 0xF0); // // If the CPU operates in both security domains, set parameters in the // control_s register. // 1. Set FIQen=1 to use FIQ for secure interrupts, // 2. Program the AckCtl bit // 3. Program the SBPR bit to select the binary pointer behavior // 4. Set EnableS = 1 to enable secure interrupts // 5. Set EnbleNS = 1 to enable non secure interrupts // // // If the CPU operates only in the secure domain, setup the // control_s register. // 1. Set FIQen=1, // 2. Set EnableS=1, to enable the CPU interface to signal secure interrupts. // Only enable the IRQ output unless secure interrupts are needed. // HAL_WRITE_UINT32(XC7Z_SCUGIC_CPU_BASEADDR + XSCUGIC_CONTROL_OFFSET, 0x07); #ifdef HAL_PLF_HARDWARE_INIT // Perform any platform specific initializations HAL_PLF_HARDWARE_INIT(); #endif #ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP HAL_DCACHE_ENABLE(); // Enable DCache #endif #ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP HAL_ICACHE_ENABLE(); // Enable ICache #endif // Set up eCos/ROM interfaces hal_if_init(); HAL_CLOCK_INITIALIZE(CYGNUM_HAL_RTC_PERIOD); #ifdef CYGPKG_HAL_SMP_SUPPORT cyg_uint32 reg; /* Disable the distributor */ HAL_READ_UINT32(XC7Z_ICD_DCR_BASEADDR, reg); reg &= ~(0x2); HAL_WRITE_UINT32(XC7Z_ICD_DCR_BASEADDR, reg); /* Clear pending interrupts */ HAL_WRITE_UINT32(XC7Z_ICD_ICPR0_BASEADDR, 0xffffffff); HAL_WRITE_UINT32(XC7Z_ICD_ICPR1_BASEADDR, 0xffffffff); HAL_WRITE_UINT32(XC7Z_ICD_ICPR2_BASEADDR, 0xffffffff); /* Re-enable the distributor */ HAL_READ_UINT32(XC7Z_ICD_DCR_BASEADDR, reg); reg |= 0x2; HAL_WRITE_UINT32(XC7Z_ICD_DCR_BASEADDR, reg); /* Start the cpu */ cyg_hal_smp_init(); hal_interrupt_init_cpu(); cyg_hal_smp_cpu_start_first(); #endif }
static void spi_at91_transfer(cyg_spi_at91_device_t *dev, cyg_uint32 count, const cyg_uint8 *tx_data, cyg_uint8 *rx_data) { cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus; // Since PDC transfer buffer counters are 16 bit long, // we have to split longer transfers into chunks. while (count > 0) { cyg_uint16 tr_count = count > 0xFFFF ? 0xFFFF : count; // Set rx buf pointer and counter if (NULL != rx_data) { HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_RPR, (cyg_uint32)rx_data); HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_RCR, (cyg_uint32)tr_count); } // Set tx buf pointer and counter HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_TPR, (cyg_uint32)tx_data); HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_TCR, (cyg_uint32)tr_count); // Enable the SPI int events we are interested in HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_IER, AT91_SPI_SR_ENDRX | AT91_SPI_SR_ENDTX); cyg_drv_mutex_lock(&spi_bus->transfer_mx); { spi_bus->transfer_end = false; // Unmask the SPI int cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_SPI); // Wait for its completition cyg_drv_dsr_lock(); { while (!spi_bus->transfer_end) cyg_drv_cond_wait(&spi_bus->transfer_cond); } cyg_drv_dsr_unlock(); } cyg_drv_mutex_unlock(&spi_bus->transfer_mx); if (NULL == rx_data) { cyg_uint32 val; // If rx buffer was NULL, then the PDC receiver data transfer // was not started and we didn't wait for ENDRX, but only for // ENDTX. Meaning that right now the last byte is being serialized // over the line and when finished input data will appear in // rx data reg. We have to wait for this to happen here, if we // don't we'll get the last received byte as the first one in the // next transfer! // FIXME: is there any better way to do this? // If not, then precalculate this value. val = 8000000/dev->cl_brate; CYGACC_CALL_IF_DELAY_US(val > 1 ? val : 1); // Clear the rx data reg HAL_READ_UINT32(AT91_SPI+AT91_SPI_RDR, val); } // Adjust running variables if (NULL != rx_data) rx_data += tr_count; tx_data += tr_count; count -= tr_count; } }
//Initializing the device static bool zynq_serial_init(struct cyg_devtab_entry *tab) { serial_channel *chan = (serial_channel *)tab->priv; zynq_serial_info *zynq_chan = (zynq_serial_info *)chan->dev_priv; cyg_uint32 pll_clock, calc_uart_clk; cyg_uint32 slcr_reg, control_reg, pll_fdiv; cyg_uint16 uart_divisor, best_uart_divisor; cyg_int32 act_error, prev_error; // Calculate DIVISOR value for UART_REF_CLK // Read I/O PLL configuration HAL_READ_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRIO_PLL_CTRL_OFFSET, pll_fdiv); // extract value of PLL divisor pll_fdiv = pll_fdiv >> 12; pll_fdiv = pll_fdiv & 0x3f; // Calculate I/O PLL freq on given PS_CLK pll_clock = PS_CLK * pll_fdiv; // Calculate best DIVISOR value to obtain UART_REF_CLK on given I/O PLL clock prev_error = UART_REF_CLK; for(uart_divisor = 1; uart_divisor < 64; uart_divisor++) { calc_uart_clk = pll_clock / uart_divisor; if(calc_uart_clk > UART_REF_CLK) act_error = calc_uart_clk - UART_REF_CLK; else act_error = UART_REF_CLK - calc_uart_clk; if(act_error < prev_error) { best_uart_divisor = uart_divisor; prev_error = act_error; } } best_uart_divisor &= 0x3f; // unlock SLCR HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCR_UNLOCK_OFFSET, XSLCR_UNLOCK_KEY); // read APER_CLK_CTRL HAL_READ_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRAPER_CLK_CTRL_OFFSET, slcr_reg); // disable AMBA Clock for unused UARTs slcr_reg &= ~(XSLCRAPER_CLK_CTRL_UART1_DIS | XSLCRAPER_CLK_CTRL_UART0_DIS); // enable AMBA Clock for used UARTs slcr_reg |= (XSLCRAPER_CLK_CTRL_UART1_EN | XSLCRAPER_CLK_CTRL_UART0_EN); // write APER_CLK_CTRL HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRAPER_CLK_CTRL_OFFSET, slcr_reg); // read UART_CLK_CTRL HAL_READ_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRUART_CLK_CTRL_OFFSET, slcr_reg); // set maximum DIVISOR so the UART_REF_CLK not exceed max value slcr_reg |= (0x3f << XSLCRUART_CLK_CTRL_DIVISOR_BITPOS); // write divisor to UART_CLK_CTRL HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRUART_CLK_CTRL_OFFSET, slcr_reg); // read UART_CLK_CTRL HAL_READ_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRUART_CLK_CTRL_OFFSET, slcr_reg); // Select the PLL source as IO PLL slcr_reg &= ~(XSLCRUART_CLK_CTRL_SRCSEL_MASK); slcr_reg |= XSLCRUART_CLK_CTRL_SRCSEL_IO_PLL_EN; // write config to UART_CLK_CTRL HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRUART_CLK_CTRL_OFFSET, slcr_reg); // read UART_CLK_CTRL HAL_READ_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRUART_CLK_CTRL_OFFSET, slcr_reg); // clear divisor field slcr_reg &= ~(XSLCRUART_CLK_CTRL_DIVISOR_MASK); // set DIVISOR slcr_reg |= (best_uart_divisor << XSLCRUART_CLK_CTRL_DIVISOR_BITPOS); // disable unused UARTs Clock in UART_CLK_CTRL slcr_reg &= ~(XSLCRUART_CLK_CTRL_CLKACT0_DIS | XSLCRUART_CLK_CTRL_CLKACT0_DIS); // enable used UARTs Clock in UART_CLK_CTRL slcr_reg |= (XSLCRUART_CLK_CTRL_CLKACT0_EN | XSLCRUART_CLK_CTRL_CLKACT0_EN); // write config to UART_CLK_CTRL HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRUART_CLK_CTRL_OFFSET, slcr_reg); // read UART Software Reset Control register HAL_READ_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRUART_RST_CTRL_OFFSET, slcr_reg); // deassert used UARTs RST slcr_reg &= ~(XSLCRUART_RST_CTRL_UART1_REF_RST | XSLCRUART_RST_CTRL_UART0_REF_RST | XSLCRUART_RST_CTRL_UART1_CPU1X_RST | XSLCRUART_RST_CTRL_UART0_CPU1X_RST); // write UART Software Reset Control register HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRUART_RST_CTRL_OFFSET, slcr_reg); // lock SLCR HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCR_LOCK_OFFSET, XSLCR_LOCK_KEY); // Initialize high level serial driver (chan->callbacks->serial_init)(chan); // Disable RX & TX HAL_WRITE_UINT32(zynq_chan->base + XUARTPS_CONTROL, XUARTPS_CONTROL_TXDIS | XUARTPS_CONTROL_RXDIS); // Reset RX & TX HAL_WRITE_UINT32(zynq_chan->base + XUARTPS_CONTROL, XUARTPS_CONTROL_TXRES | XUARTPS_CONTROL_RXRES); // Enable RX & TX HAL_READ_UINT32(zynq_chan->base + XUARTPS_CONTROL, control_reg); control_reg &= ~(XUARTPS_CONTROL_TXDIS | XUARTPS_CONTROL_RXDIS); control_reg |= (XUARTPS_CONTROL_TXEN | XUARTPS_CONTROL_RXEN); HAL_WRITE_UINT32(zynq_chan->base + XUARTPS_CONTROL, control_reg); // configure port zynq_serial_config_port(chan, &chan->config, true); // set receiver receiver trigger level HAL_WRITE_UINT32(zynq_chan->base + XUARTPS_RX_WM, 56); // set receiver timeout value HAL_WRITE_UINT32(zynq_chan->base + XUARTPS_RX_TOUT, 10); // Register interrupt (only if buffers are defined) if (chan->out_cbuf.len != 0) { cyg_drv_interrupt_create(zynq_chan->int_num, 0, (cyg_addrword_t)chan, // Data item passed to interrupt handler zynq_serial_ISR, zynq_serial_DSR, &zynq_chan->serial_interrupt_handle, &zynq_chan->serial_interrupt); cyg_drv_interrupt_attach(zynq_chan->serial_interrupt_handle); cyg_drv_interrupt_unmask(zynq_chan->int_num); } // clear ISR status register HAL_READ_UINT32(zynq_chan->base + XUARTPS_CHNL_INT_STS, control_reg); HAL_WRITE_UINT32(zynq_chan->base + XUARTPS_CHNL_INT_STS, control_reg); // enable receiver interrupts HAL_WRITE_UINT32(zynq_chan->base + XUARTPS_INTRPT_EN, XUARTPS_INTRPT_EN_RTRIG | XUARTPS_INTRPT_EN_TIMEOUT); return true; }
//========================================================================== // This function is called from the device IO infrastructure to initialize // the device. It should perform any work needed to start up the device, // short of actually starting the generation of samples. This function will // be called for each channel, so if there is initialization that only needs // to be done once, such as creating and interrupt object, then care should // be taken to do this. This function should also call cyg_adc_device_init() // to initialize the generic parts of the driver. //========================================================================== static bool at91_adc_init(struct cyg_devtab_entry *tab) { cyg_adc_channel *chan = (cyg_adc_channel *)tab->priv; cyg_adc_device *device = chan->device; at91_adc_info *info = device->dev_priv; cyg_uint32 regval; if (!info->int_handle) { cyg_drv_interrupt_create(info->timer_vector, info->timer_intprio, (cyg_addrword_t)device, &at91_adc_isr, &at91_adc_dsr, &(info->int_handle), &(info->int_data)); cyg_drv_interrupt_attach(info->int_handle); cyg_drv_interrupt_mask(info->timer_vector); // Reset ADC HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_SWRST); // Disable counter interrupts HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_CLKDIS); HAL_WRITE_UINT32(info->tc_base+AT91_TC_IDR, 0xffffffff); // Clear status bit HAL_READ_UINT32(info->tc_base + AT91_TC_SR, regval); // Enable peripheral clocks for TC HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, \ ((AT91_PMC_PCER_TC0) << info->timer_id)); // // Disable all interrupts, all channels // HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHDR), \ AT91_ADC_CHER_CH0 |\ AT91_ADC_CHER_CH1 |\ AT91_ADC_CHER_CH2 |\ AT91_ADC_CHER_CH3 |\ AT91_ADC_CHER_CH4 |\ AT91_ADC_CHER_CH5 |\ AT91_ADC_CHER_CH6 |\ AT91_ADC_CHER_CH7); HAL_WRITE_UINT32((info->adc_base + AT91_ADC_IDR), \ AT91_ADC_CHER_CH0 |\ AT91_ADC_CHER_CH1 |\ AT91_ADC_CHER_CH2 |\ AT91_ADC_CHER_CH3 |\ AT91_ADC_CHER_CH4 |\ AT91_ADC_CHER_CH5 |\ AT91_ADC_CHER_CH6 |\ AT91_ADC_CHER_CH7); // // setup the default sample rate // at91_adc_set_rate(chan, chan->device->config.rate); // setup ADC mode HAL_WRITE_UINT32((info->adc_base + AT91_ADC_MR), \ ( ( info->adc_prescal << AT91_ADC_MR_PRESCAL_SHIFT ) & \ AT91_ADC_MR_PRESCAL_MASK ) | \ ( ( info->adc_startup_time << AT91_ADC_MR_STARTUP_SHIFT ) & \ AT91_ADC_MR_STARTUP_MASK ) | \ ( ( info->adc_shtim << AT91_ADC_MR_SHTIM_SHIFT ) & \ AT91_ADC_MR_SHTIM_MASK ) | \ AT91_ADC_MR_TRGSEL_TIOA0 | \ info->resolution); } // if (!info->int_handle) cyg_adc_device_init(device); // initialize generic parts of driver return true; }
/** * * QSPI bus transfer with IRQ function. * * @param qspi_bus - QSPI bus handle * @param count - Number of bytes to transmit. * @param tx_data - Pointer to TX buffer. * @param rx_data - Pointer to RX buffer. * * @return none * *****************************************************************************/ static void qspi_xc7z_transfer(cyg_qspi_xc7z_device_t *dev, cyg_uint32 count, const cyg_uint8 *tx_data, cyg_uint8 *rx_data) { entry_debug(); cyg_qspi_xc7z_bus_t *qspi_bus = (cyg_qspi_xc7z_bus_t *)dev->qspi_device.spi_bus; cyg_uint32 val; // Enable device HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_ER_OFFSET, XQSPIPS_ER_ENABLE_MASK); // Enable manual start HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, val); val |= XQSPIPS_CR_MANSTRTEN_MASK | XQSPIPS_CR_SSFORCE_MASK; HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, val); // Set tx buf pointer and counter if (NULL != tx_data) HAL_DCACHE_STORE(tx_data, count); // Set rx buf pointer and counter if (NULL != rx_data) HAL_DCACHE_FLUSH(rx_data, count); // Send first instruction if(qspi_bus->uc_tx_instr == 0) qspi_xc7z_send_instruction(qspi_bus); { if ((qspi_bus->us_tx_bytes) && ((qspi_bus->uc_tx_instr != XQSPIPS_FLASH_OPCODE_FAST_READ) || (qspi_bus->uc_tx_instr != XQSPIPS_FLASH_OPCODE_DUAL_READ) || (qspi_bus->uc_tx_instr != XQSPIPS_FLASH_OPCODE_QUAD_READ) )) qspi_xc7z_fill_tx_fifo(qspi_bus,count); // Enable the QSPI int events we are interested in HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_IER_OFFSET, XQSPIPS_IXR_TXOW_MASK | XQSPIPS_IXR_MODF_MASK); HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, val); val |= XQSPIPS_CR_MANSTRT_MASK; HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, val); cyg_drv_mutex_lock(&qspi_bus->transfer_mx); { qspi_bus->transfer_end = false; // Unmask the SPI int cyg_drv_interrupt_unmask(qspi_bus->interrupt_number); // Wait for its completion cyg_drv_dsr_lock(); { while (!qspi_bus->transfer_end) cyg_drv_cond_wait(&qspi_bus->transfer_cond); } cyg_drv_dsr_unlock(); } cyg_drv_mutex_unlock(&qspi_bus->transfer_mx); } }
/** * * QSPI bus interrupt service routine * * @param vector - Number of ISR * @param data - Pointer to data structure (with driver handle) * * @return ISR return condition * *****************************************************************************/ static cyg_uint32 qspi_xc7z_ISR(cyg_vector_t vector, cyg_addrword_t data) { cyg_uint32 stat; cyg_uint32 val; cyg_qspi_xc7z_bus_t * qspi_bus = (cyg_qspi_xc7z_bus_t *)data; cyg_uint32 return_cond = CYG_ISR_HANDLED; // Read the status register and clear interrupt immediately // the SPI int events that have occurred HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, stat); HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, stat); // Read the status register and // check for transfer completion HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, stat); HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, stat); //TODO: is it necessary if(stat & XQSPIPS_IXR_MODF_MASK) { cyg_drv_interrupt_mask(vector); return_cond |= CYG_ISR_CALL_DSR; } else { if ((stat & XQSPIPS_IXR_TXOW_MASK) || (stat & XQSPIPS_IXR_RXNEMPTY_MASK)) { /* Read out the data from the RX FIFO */ HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, val); while (val & XQSPIPS_IXR_RXNEMPTY_MASK) { HAL_READ_UINT32(qspi_bus->base + XQSPIPS_RXD_OFFSET, val); if (qspi_bus->us_rx_bytes < 4) qspi_xc7z_copy_read_data(qspi_bus, val, qspi_bus->us_rx_bytes); else qspi_xc7z_copy_read_data(qspi_bus, val, 4); HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, val); } if (qspi_bus->us_tx_bytes){ qspi_xc7z_fill_tx_fifo(qspi_bus,8); HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_IER_OFFSET, XQSPIPS_IXR_TXOW_MASK | XQSPIPS_IXR_MODF_MASK); // Transfer still in progress - unmask the SPI // int so we can get more SPI int events cyg_drv_interrupt_unmask(vector); HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, val); val |= XQSPIPS_CR_MANSTRT_MASK; HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, val); } else if (qspi_bus->us_rx_bytes){ /* Read out the data from the RX FIFO */ HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, val); while (val & XQSPIPS_IXR_RXNEMPTY_MASK) { HAL_READ_UINT32(qspi_bus->base + XQSPIPS_RXD_OFFSET, val); if (qspi_bus->us_rx_bytes < 4) qspi_xc7z_copy_read_data(qspi_bus, val, qspi_bus->us_rx_bytes); else qspi_xc7z_copy_read_data(qspi_bus, val, 4); HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, val); } } else { cyg_drv_interrupt_mask(vector); return_cond |= CYG_ISR_CALL_DSR; } } } cyg_drv_interrupt_acknowledge(vector); return return_cond; }
static int cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...) { #if 0 /* No interrupts yet */ static int irq_state = 0; #endif channel_data_t* chan; cyg_uint8 ier; int ret = 0; CYGARC_HAL_SAVE_GP(); // Some of the diagnostic print code calls through here with no idea what the ch_data is. // Go ahead and assume it is channels[0]. if (__ch_data == 0) __ch_data = (void*)&channels[0]; chan = (channel_data_t*)__ch_data; switch (__func) { #if 0 /* No interrupts yet */ case __COMMCTL_IRQ_ENABLE: irq_state = 1; HAL_READ_UINT32(chan->base + SER_16550_IER, ier); ier |= SIO_IER_ERDAI; HAL_WRITE_UINT32(chan->base + SER_16550_IER, ier); HAL_INTERRUPT_SET_LEVEL(chan->isr_vector, 1); HAL_INTERRUPT_UNMASK(chan->isr_vector); break; case __COMMCTL_IRQ_DISABLE: ret = irq_state; irq_state = 0; HAL_READ_UINT32(chan->base + SER_16550_IER, ier); ier &= ~SIO_IER_ERDAI; HAL_WRITE_UINT32(chan->base + SER_16550_IER, ier); HAL_INTERRUPT_MASK(chan->isr_vector); break; case __COMMCTL_DBG_ISR_VECTOR: ret = chan->isr_vector; break; #endif case __COMMCTL_SET_TIMEOUT: { va_list ap; va_start(ap, __func); ret = chan->msec_timeout; chan->msec_timeout = va_arg(ap, cyg_uint32); va_end(ap); } break; case __COMMCTL_SETBAUD: { cyg_uint32 baud_rate; cyg_uint16 baud_divisor; CYG_ADDRWORD port = chan->base; va_list ap; va_start(ap, __func); baud_rate = va_arg(ap, cyg_uint32); va_end(ap); baud_divisor = (ar7240_ahb_freq / 16 / baud_rate); // Disable port interrupts while changing hardware HAL_READ_UINT32(port+SER_16550_IER, ier); HAL_WRITE_UINT32(port+SER_16550_IER, 0); // Set baud rate. cyg_hal_plf_serial_set_baud(port, baud_divisor); // Reenable interrupts if necessary HAL_WRITE_UINT32(port+SER_16550_IER, ier); } break; case __COMMCTL_GETBAUD: break; default: break; } CYGARC_HAL_RESTORE_GP(); return ret; }
// Initialize the hardware. Make sure we have a flash device we know // how to program and determine its size, the size of the blocks, and // the number of blocks. The query function returns the chip ID 1 // register which tells us about the CPU we are running on, the flash // size etc. Use this information to determine we have a valid setup. int flash_hwr_init(void){ cyg_uint32 chipID1r; cyg_uint32 flash_mode; cyg_uint8 fmcn; cyg_uint32 lock_bits; flash_query (&chipID1r); if ((chipID1r & AT91_DBG_C1R_CPU_MASK) != AT91_DBG_C1R_ARM7TDMI) goto out; if (((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7Sxx) && ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7Xxx) && ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7XC) && ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7SExx)) goto out; if ((chipID1r & AT91_DBG_C1R_FLASH_MASK) == AT91_DBG_C1R_FLASH_0K) goto out; if ((chipID1r & AT91_DBG_C1R_NVPTYP_MASK) != AT91_DBG_C1R_NVPTYP_ROMFLASH) { switch (chipID1r & AT91_DBG_C1R_FLASH_MASK) { case AT91_DBG_C1R_FLASH_32K: flash_info.block_size = 128; flash_info.blocks = 256; lock_bits = 8; break; case AT91_DBG_C1R_FLASH_64K: flash_info.block_size = 128; flash_info.blocks = 512; lock_bits = 16; break; case AT91_DBG_C1R_FLASH_128K: flash_info.block_size = 256; flash_info.blocks = 512; lock_bits = 8; break; case AT91_DBG_C1R_FLASH_256K: flash_info.block_size = 256; flash_info.blocks = 1024; lock_bits = 16; break; #ifdef AT91_MC_FMR1 case AT91_DBG_C1R_FLASH_512K: flash_info.block_size = 256; flash_info.blocks = 1024; lock_bits = 16; (*flash_info.pf)("at91_flash: Only EFC0 is supported for writes and locks"); //flash_info.blocks = 2048; //lock_bits = 32; break; #endif default: goto out; } } else { // if there is both flash & ROM then: ROM=AT91_DBG_C1R_FLASH, flash=AT91_DBG_C1R_FLASH2 switch (chipID1r & AT91_DBG_C1R_FLASH2_MASK) { case AT91_DBG_C1R_FLASH2_32K: flash_info.block_size = 128; flash_info.blocks = 256; lock_bits = 8; break; case AT91_DBG_C1R_FLASH2_64K: flash_info.block_size = 128; flash_info.blocks = 512; lock_bits = 16; break; case AT91_DBG_C1R_FLASH2_128K: flash_info.block_size = 256; flash_info.blocks = 512; lock_bits = 8; break; case AT91_DBG_C1R_FLASH2_256K: flash_info.block_size = 256; flash_info.blocks = 1024; lock_bits = 16; break; #ifdef AT91_MC_FMR1 case AT91_DBG_C1R_FLASH2_512K: flash_info.block_size = 256; flash_info.blocks = 1024; lock_bits = 16; (*flash_info.pf)("at91_flash: Only EFC0 is supported for writes and locks"); //flash_info.blocks = 2048; //lock_bits = 32; break; #endif default: goto out; } } flash_info.buffer_size = 0; flash_info.start = (void *) 0x00100000; flash_info.end = (void *)(((cyg_uint32) flash_info.start) + flash_info.block_size * flash_info.blocks); #ifdef CYGBLD_DEV_FLASH_AT91_LOCKING sector_size = flash_info.block_size * flash_info.blocks / lock_bits; #endif // Set the FLASH clock to 1.5 microseconds based on the MCLK. This // assumes the CPU is still running from the PLL clock as defined in // the HAL CDL and the HAL startup code. fmcn = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 1.5 / 1000000 + 0.999999; // We must round up! HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, flash_mode); flash_mode = flash_mode & ~AT91_MC_FMR_FMCN_MASK; flash_mode = flash_mode | (fmcn << AT91_MC_FMR_FMCN_SHIFT); HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, flash_mode); #ifdef AT91_MC_FMR1 HAL_READ_UINT32(AT91_MC+AT91_MC_FMR1, flash_mode); flash_mode = flash_mode & ~AT91_MC_FMR_FMCN_MASK; flash_mode = flash_mode | (fmcn << AT91_MC_FMR_FMCN_SHIFT); HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, flash_mode); #endif return FLASH_ERR_OK; out: (*flash_info.pf)("Can't identify FLASH, sorry, ChipID1 %x\n", chipID1r ); return FLASH_ERR_HWR; }
__externC void hal_system_init( void ) { CYG_ADDRESS base; // Enable peripheral clocks in RCC base = CYGHWR_HAL_STM32_RCC; // All GPIO ports // FIXME: this should be done in variant HAL at point of gpio_set HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_AHB1ENR, #if defined(CYGHWR_HAL_CORTEXM_STM32_FAMILY_F4) // enable CCM clock BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_CCMDATARAMEN) | #endif // CYGHWR_HAL_CORTEXM_STM32_FAMILY_F4 BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOA) | BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOB) | BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOC) | BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOD) | BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOE) | BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOF) | BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOG) | BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOH) | BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOI) ); // Enable FSMC HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_AHB3ENR, BIT_(CYGHWR_HAL_STM32_RCC_AHB3ENR_FSMC) ); #if defined(CYG_HAL_STARTUP_ROM) | defined(CYG_HAL_STARTUP_ROMINT) | defined(CYG_HAL_STARTUP_SRAM) // Reset FSMC in case it was already enabled. This should set // all regs back to default documented values, so we don't need // to do any precautionary resets. HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_AHB3RSTR, BIT_(CYGHWR_HAL_STM32_RCC_AHB3ENR_FSMC) ); // Bring out of reset: HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_AHB3RSTR, 0 ); #endif #if defined(CYGHWR_HAL_CORTEXM_STM32X0G_ETH_PHY_CLOCK_MCO) // Use HSE clock as the MCO1 clock signals for PHY { cyg_uint32 acr; HAL_READ_UINT32(base + CYGHWR_HAL_STM32_RCC_CFGR, acr); acr |= CYGHWR_HAL_STM32_RCC_CFGR_MCO1_HSE | CYGHWR_HAL_STM32_RCC_CFGR_MCO1PRE_1; HAL_WRITE_UINT32(base + CYGHWR_HAL_STM32_RCC_CFGR, acr); } #endif // Set all unused GPIO lines to input with pull down to prevent // them floating and annoying any external hardware. // GPIO Ports C..I reset GPIOx_MODER to 0x00000000 // GPIO Ports A..I reset GPIOx_OTYPER to 0x00000000 // CPIO Ports A,C..I reset GPIOx_OSPEEDR to 0x00000000 // GPIO Ports C..I reset GPIOx_PUPDR to 0x00000000 // GPIO Port A resets GPIOA_MODER to 0xA8000000 // GPIO Port A resets GPIOA_PUPDR to 0x64000000 // GPIO Port A keeps the default JTAG pins on PA13,14,15 base = CYGHWR_HAL_STM32_GPIOA; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0x02AAAAAA ); // GPIO Port B resets GPIOB_MODER to 0x00000280 // GPIO Port B resets GPIOB_OSPEEDR to 0x000000C0 // GPIO Port B resets GPIOB_PUPDR to 0x00000100 // GPIO Port B keeps the default JTAG pins on PB3,4 base = CYGHWR_HAL_STM32_GPIOB; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0xAAAAA82A ); // GPIO Port C - setup PC7 for LED4 as GPIO out, RS232 (USART4) on PC10,11. // Rest stay default, with pulldowns on all except PC14,15 (OSC32) // just in case that is important. base = CYGHWR_HAL_STM32_GPIOC; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0x00008800 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0x0A0A2AAA ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0x00A04000 ); // GPIO Port D - setup FSMC for SRAM (PD0-1,3-15) and MicroSDcard (PD2) alternate functions base = CYGHWR_HAL_STM32_GPIOD; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRL, 0xCCCCCCCC ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0xCCCCCCCC ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0xAAAAAAAA ); // TODO:CONSIDER: OSPEEDR for SRAM pins to 100MHz // GPIO Port E - setup FSMC alternate function. PE0-1,3-4,7-15. // But not PE5 (A21), PE6(A22), PE2(A23) which are not connected to SRAM. base = CYGHWR_HAL_STM32_GPIOE; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRL, 0xC00CC0CC ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0xCCCCCCCC ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0x00002820 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0xAAAA828A ); // TODO:CONSIDER: OSPEEDR for SRAM pins to 100MHz // GPIO Port F - setup FSMC alternate function. PF0-5,12-15. // But not PF6-11 which aren't connected to SRAM. base = CYGHWR_HAL_STM32_GPIOF; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRL, 0x00CCCCCC ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0xCCCC0000 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0x00AAA000 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0xAA000AAA ); // TODO:CONSIDER: OSPEEDR for SRAM pins to 100MHz // GPIO Port G - setup FSMC alternate function. PG0-5,9,10. // Other FSMC pins not connected to SRAM. // LED1 is PG6, LED2 is PG8, so set as GPIO out. base = CYGHWR_HAL_STM32_GPIOG; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRL, 0x00CCCCCC ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0x00000CC0 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0xAA808000 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0x00291AAA ); // TODO:CONSIDER: OSPEEDR for SRAM pins to 100MHz // GPIO Port H stays default, with pulldowns on all except PH0,1 (OSC) just in case that is important. base = CYGHWR_HAL_STM32_GPIOH; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0xAAAAAAA0 ); // GPIO Port I - setup PI9 for LED3 as GPIO out, rest stay default, with pulldowns base = CYGHWR_HAL_STM32_GPIOI; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0xAAA2AAAA ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0x00040000 ); // Set up FSMC NOR/SRAM bank 2 for SRAM base = CYGHWR_HAL_STM32_FSMC; #if defined(CYGHWR_HAL_CORTEXM_STM32_FAMILY_F4) // NOTEs: // - The "STM32 20-21-45-46 G-EVAL" boards we have are populated with the // IS61WV102416BLL-10MLI part and not the Cypress CY7C1071DV33 part. // - The F4[01][57]xx devices can operate upto 168MHz (or 144MHz) so maximum HCLK // timing of 6ns (or 6.94444ns). // // NOTE: The code does NOT set BWTR2 for SRAM write-cycle timing (so will be // the default reset value of 0x0FFFFFFF) since BCRx:EXTMOD bit is NOT set. // TODO:IMPROVE: Derive values based on CLK settings. The following "fixed" // values are based on a 168MHz SYSCLK: // BCR2 = MBKEN | MWID=0b01 (16bits) | WREN HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR2, 0x00001015 ); // BTR2: // ADDSET=3 (3 HCLK cycles) // ADDHLD=0 (SRAM:do not care) // DATAST=6 (6 HCLK cycles) // BUSTURN=1 (1 HCLK cycle) // CLKDIV=0 (SRAM:do not care) // DATLAT=0 (SRAM:do not care) // ACCMOD=0 (access mode A) HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR2, 0x00010603 ); #else // CYGHWR_HAL_CORTEXM_STM32_FAMILY_F2 HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR2, 0x00001011 ); // SRAM timings for the fitted CY7C1071DV33-12BAXI async SRAM // We could try and make this depend on hclk as it should, but that's // probably overkill for now. With an hclk of 120MHz, each hclk period // is 8.33ns, so we just use that. This might mean being slightly // suboptimal at lower configured hclk speeds. // It's tricky to get the waveforms in the STM32 FSMC docs and the SRAM // datasheet, to match up, so there's a small amount of guess work involved // here. From the SRAM datasheet, ADDSET should be at least 7ns (tHZWE), and // DATAST should be at least 9ns (tPWE) plus one HCLK (from Fig 397 in FSMC // docs showing Mode 1 write accesses). This gives ADDSET=1 and // DATAST=3. HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR2, 0x00000301 ); #endif // CYGHWR_HAL_CORTEXM_STM32_FAMILY_F2 // Enable flash prefetch buffer, cacheability and set latency to 2 wait states. // Latency has to be set before clock is switched to a higher speed. { cyg_uint32 acr; base = CYGHWR_HAL_STM32_FLASH; HAL_READ_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr ); acr |= CYGHWR_HAL_STM32_FLASH_ACR_PRFTEN; acr |= CYGHWR_HAL_STM32_FLASH_ACR_DCEN|CYGHWR_HAL_STM32_FLASH_ACR_ICEN; acr |= CYGHWR_HAL_STM32_FLASH_ACR_LATENCY(CYGNUM_HAL_CORTEXM_STM32_FLASH_WAIT_STATES); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr ); } }
/// Main function, primary avionics functions, thread 0, highest priority. int main(int argc, char **argv) { // Data Structures struct imu imuData; struct xray xrayData; struct gps gpsData; struct nav navData; struct control controlData; uint16_t cpuLoad; // Timing variables double etime_daq, etime_datalog, etime_telemetry; // Include datalog definition #include DATALOG_CONFIG // Populate dataLog members with initial values // dataLog.saveAsDoubleNames = &saveAsDoubleNames[0]; dataLog.saveAsDoublePointers = &saveAsDoublePointers[0]; dataLog.saveAsFloatNames = &saveAsFloatNames[0]; dataLog.saveAsFloatPointers = &saveAsFloatPointers[0]; dataLog.saveAsXrayNames = &saveAsXrayNames[0]; dataLog.saveAsXrayPointers = &saveAsXrayPointers[0]; dataLog.saveAsIntNames = &saveAsIntNames[0]; dataLog.saveAsIntPointers = &saveAsIntPointers[0]; dataLog.saveAsShortNames = &saveAsShortNames[0]; dataLog.saveAsShortPointers = &saveAsShortPointers[0]; dataLog.logArraySize = LOG_ARRAY_SIZE; dataLog.numDoubleVars = NUM_DOUBLE_VARS; dataLog.numFloatVars = NUM_FLOAT_VARS; dataLog.numXrayVars = NUM_XRAY_VARS; dataLog.numIntVars = NUM_INT_VARS; dataLog.numShortVars = NUM_SHORT_VARS; double tic,time,t0=0; static int t0_latched = FALSE; int loop_counter = 0; pthread_mutex_t mutex; uint32_t cpuCalibrationData;//, last100ms, last1s, last10s; cyg_cpuload_t cpuload; cyg_handle_t loadhandle; // Populate sensorData structure with pointers to data structures // sensorData.imuData_ptr = &imuData; sensorData.gpsData_ptr = &gpsData; sensorData.xrayData_ptr = &xrayData; // Set main thread to highest priority // struct sched_param param; param.sched_priority = sched_get_priority_max(SCHED_FIFO); pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); // Setup CPU load measurements // cyg_cpuload_calibrate(&cpuCalibrationData); cyg_cpuload_create(&cpuload, cpuCalibrationData, &loadhandle); // Initialize set_actuators (PWM or serial) at zero // // init_actuators(); // set_actuators(&controlData); // Initialize mutex variable. Needed for pthread_cond_wait function // pthread_mutex_init(&mutex, NULL); pthread_mutex_lock(&mutex); // Initialize functions // init_daq(&sensorData, &navData, &controlData); init_telemetry(); while(1){ //Init Interrupts printf("intr init"); cyg_uint32 uChannel = MPC5XXX_GPW_GPIO_WKUP_7; BOOL enable = true; BOOL bInput = 1; // uChannel initialisation GPIO_GPW_EnableGPIO(uChannel, enable); GPIO_GPW_SetDirection(uChannel, bInput); GPIO_GPW_EnableInterrupt(uChannel, enable, MPC5XXX_GPIO_INTTYPE_RISING); GPIO_GPW_ClearInterrupt(uChannel); HAL_WRITE_UINT32(MPC5XXX_GPW+MPC5XXX_GPW_ME, 0x01000000); cyg_uint32 temp; HAL_READ_UINT32(MPC5XXX_ICTL_MIMR, temp); HAL_WRITE_UINT32(MPC5XXX_ICTL_MIMR, temp&0xFFFFFEFF); // wake-up interrupt service routine initialisation cyg_vector_t int1_vector = CYGNUM_HAL_INTERRUPT_GPIO_WAKEUP; cyg_priority_t int1_priority = 0; cyg_bool_t edge = 0; cyg_bool_t rise = 1; cyg_drv_interrupt_create(int1_vector, int1_priority,0,interrupt_1_isr, interrupt_1_dsr,&int1_handle,&int1); cyg_drv_interrupt_attach(int1_handle); cyg_drv_interrupt_configure(int1_vector,edge,rise); cyg_drv_interrupt_unmask(int1_vector); hasp_mpc5xxx_i2c_init(); // Append: Initialise I2C bus and I2C interrupt routine; device defined in i2c_mpc5xxx.h and .c cyg_interrupt_enable(); HAL_ENABLE_INTERRUPTS(); controlData.mode = 1; // initialize to manual mode controlData.run_num = 0; // reset run counter reset_Time(); // initialize real time clock at zero init_scheduler(); // Initialize scheduling threads_create(); // start additional threads init_datalogger(); // Initialize data logging //+++++++++++// // Main Loop // //+++++++++++// while (controlData.mode != 0) { loop_counter++; //.increment loop counter //**** DATA ACQUISITION ************************************************** pthread_cond_wait (&trigger_daq, &mutex); tic = get_Time(); get_daq(&sensorData, &navData, &controlData); etime_daq = get_Time() - tic - DAQ_OFFSET; // compute execution time //************************************************************************ //**** NAVIGATION ******************************************************** // pthread_cond_wait (&trigger_nav, &mutex); // if(navData.err_type == got_invalid){ // check if get_nav filter has been initialized // if(gpsData.navValid == 0) // check if GPS is locked // init_nav(&sensorData, &navData, &controlData);// Initialize get_nav filter // } // else // get_nav(&sensorData, &navData, &controlData);// Call NAV filter //************************************************************************ if (controlData.mode == 2) { // autopilot mode if (t0_latched == FALSE) { t0 = get_Time(); t0_latched = TRUE; } time = get_Time()-t0; // Time since in auto mode } else{ if (t0_latched == TRUE) { t0_latched = FALSE; } //reset_control(&controlData); // reset controller states and set get_control surfaces to zero } // end if (controlData.mode == 2) // Add trim biases to get_control surface commands //add_trim_bias(&controlData); //**** DATA LOGGING ****************************************************** pthread_cond_wait (&trigger_datalogger, &mutex); datalogger(&sensorData, &navData, &controlData, cpuLoad); cyg_drv_interrupt_mask(int1_vector); xray_dump = dataprinter(sensorData, xray_dump); cyg_drv_interrupt_unmask(int1_vector); etime_datalog = get_Time() - tic - DATALOG_OFFSET; // compute execution time //************************************************************************ //**** TELEMETRY ********************************************************* if(loop_counter >= BASE_HZ/TELEMETRY_HZ){ loop_counter = 0; pthread_cond_wait (&trigger_telemetry, &mutex); // // get current cpu load // cyg_cpuload_get (loadhandle, &last100ms, &last1s, &last10s); // cpuLoad = (uint16_t)last100ms; // send_telemetry(&sensorData, &navData, &controlData, cpuLoad); // // etime_telemetry = get_Time() - tic - TELEMETRY_OFFSET; // compute execution time } //************************************************************************ } //end while (controlData.mode != 0) close_scheduler(); close_datalogger(); // dump data } // end while(1) /********************************************************************** * close **********************************************************************/ pthread_mutex_destroy(&mutex); // close_actuators(); //close_nav(); return 0; } // end main
static cyg_uint32 zynq_slcr_read(cyg_uint32 reg) { cyg_uint32 value; HAL_READ_UINT32(XSLR_BASE + reg, value); return value; }
void hal_reset_vsr( void ) { // Call system init routine. This should do the minimum necessary // for the rest of the initialization to complete. For example set // up GPIO, the SRAM, power management etc. This routine is // usually supplied by the platform HAL. Calls to // hal_variant_init() and hal_platform_init() later will perform // the main initialization. hal_system_init(); // Initialize vector table in base of SRAM. { register int i; #if !defined(CYG_HAL_STARTUP_RAM) // Only install the exception vectors for non-RAM startup. For // RAM startup we want these to continue to point to the original // VSRs, which will belong to RedBoot or GDB stubs. for( i = 2; i < 15; i++ ) hal_vsr_table[i] = (CYG_ADDRESS)hal_default_exception_vsr; #endif // Always point SVC and PENDSVC vectors to our local versions hal_vsr_table[CYGNUM_HAL_VECTOR_SERVICE] = (CYG_ADDRESS)hal_default_svc_vsr; hal_vsr_table[CYGNUM_HAL_VECTOR_PENDSV] = (CYG_ADDRESS)hal_pendable_svc_vsr; // For all startup type, redirect interrupt vectors to our VSR. for( i = CYGNUM_HAL_VECTOR_SYS_TICK ; i < CYGNUM_HAL_VECTOR_SYS_TICK + CYGNUM_HAL_VSR_MAX; i++ ) hal_vsr_table[i] = (CYG_ADDRESS)hal_default_interrupt_vsr; } #if !defined(CYG_HAL_STARTUP_RAM) // Ensure that the CPU will use the vector table we have just set // up. # if defined(CYGHWR_HAL_CORTEXM_M3) // On M3 parts, the NVIC contains a vector table base register. We // program this to relocate the vector table base to the base of // SRAM. HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_VTOR, CYGARC_REG_NVIC_VTOR_TBLOFF(0)| CYGARC_REG_NVIC_VTOR_TBLBASE_SRAM ); # else # error Unknown SRAM/VECTAB remap mechanism # endif // Use SVC to switch our state to thread mode running on the PSP. // We don't need to do this for RAM startup since the ROM code // will have already done it. hal_vsr_table[CYGNUM_HAL_VECTOR_SERVICE] = (CYG_ADDRESS)hal_switch_state_vsr; __asm__ volatile( "swi" ); hal_vsr_table[CYGNUM_HAL_VECTOR_SERVICE] = (CYG_ADDRESS)hal_default_svc_vsr; #endif // !defined(CYG_HAL_STARTUP_RAM) #if defined(CYG_HAL_STARTUP_ROM) // Relocate data from ROM to RAM { register cyg_uint32 *p, *q; for( p = &__ram_data_start, q = &__rom_data_start; p < &__ram_data_end; p++, q++ ) *p = *q; } /* // Relocate data from ROM to SRAM { register cyg_uint32 *p, *q; for( p = &__sram_data_start, q = &__srom_data_start; p < &__sram_data_end; p++, q++ ) *p = *q; } */ #endif // Clear BSS { register cyg_uint32 *p; for( p = &__bss_start; p < &__bss_end; p++ ) *p = 0; } // Initialize interrupt vectors. Set the levels for all interrupts // to default values. Also set the default priorities of the // system handlers: all exceptions maximum priority except SVC and // PendSVC which are lowest priority. { register int i; HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SHPR0, 0x00000000 ); HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SHPR1, 0xFF000000 ); HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SHPR2, 0x00FF0000 ); hal_interrupt_handlers[CYGNUM_HAL_INTERRUPT_SYS_TICK] = (CYG_ADDRESS)hal_default_isr; for( i = 1; i < CYGNUM_HAL_ISR_COUNT; i++ ) { hal_interrupt_handlers[i] = (CYG_ADDRESS)hal_default_isr; HAL_WRITE_UINT8( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_PR(i-CYGNUM_HAL_INTERRUPT_EXTERNAL), 0x80 ); } } #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) // Enable DebugMonitor exceptions. This is needed to enable single // step. This only has an effect if no external JTAG device is // attached. { CYG_ADDRESS base = CYGARC_REG_DEBUG_BASE; cyg_uint32 demcr; HAL_READ_UINT32( base+CYGARC_REG_DEBUG_DEMCR, demcr ); demcr |= CYGARC_REG_DEBUG_DEMCR_MON_EN; HAL_WRITE_UINT32( base+CYGARC_REG_DEBUG_DEMCR, demcr ); } #endif #if !defined(CYG_HAL_STARTUP_RAM) // Enable Usage, Bus and Mem fault handlers. Do this for ROM and // JTAG startups. For RAM startups, this will have already been // done by the ROM monitor. { CYG_ADDRESS base = CYGARC_REG_NVIC_BASE; cyg_uint32 shcsr; HAL_READ_UINT32( base+CYGARC_REG_NVIC_SHCSR, shcsr ); shcsr |= CYGARC_REG_NVIC_SHCSR_USGFAULTENA; shcsr |= CYGARC_REG_NVIC_SHCSR_BUSFAULTENA; shcsr |= CYGARC_REG_NVIC_SHCSR_MEMFAULTENA; HAL_WRITE_UINT32( base+CYGARC_REG_NVIC_SHCSR, shcsr ); } #endif // Call variant and platform init routines hal_variant_init(); hal_platform_init(); // Start up the system clock HAL_CLOCK_INITIALIZE( CYGNUM_HAL_RTC_PERIOD ); #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS initialize_stub(); #endif #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || \ defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) hal_ctrlc_isr_init(); #endif // Run through static constructors cyg_hal_invoke_constructors(); // Finally call into application cyg_start(); for(;;); }
__externC void hal_system_init( void ) { CYG_ADDRESS base; #if defined(CYG_HAL_STARTUP_ROM) | defined(CYG_HAL_STARTUP_ROMINT) | defined(CYG_HAL_STARTUP_SRAM) // Enable peripheral clocks in RCC base = CYGHWR_HAL_STM32_RCC; HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_AHBENR, BIT_(CYGHWR_HAL_STM32_RCC_AHBENR_FSMC) | BIT_(CYGHWR_HAL_STM32_RCC_AHBENR_FLITF) | BIT_(CYGHWR_HAL_STM32_RCC_AHBENR_SRAM) ); HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_APB2ENR, BIT_(CYGHWR_HAL_STM32_RCC_APB2ENR_IOPA) | BIT_(CYGHWR_HAL_STM32_RCC_APB2ENR_IOPB) | BIT_(CYGHWR_HAL_STM32_RCC_APB2ENR_IOPC) | BIT_(CYGHWR_HAL_STM32_RCC_APB2ENR_IOPD) | BIT_(CYGHWR_HAL_STM32_RCC_APB2ENR_IOPE) | BIT_(CYGHWR_HAL_STM32_RCC_APB2ENR_IOPF) | BIT_(CYGHWR_HAL_STM32_RCC_APB2ENR_IOPG) ); // Set all unused GPIO lines to input with pull down to prevent // them floating and annoying any external hardware. base = CYGHWR_HAL_STM32_GPIOA; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRL, 0x88888888 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRH, 0x88888888 ); base = CYGHWR_HAL_STM32_GPIOB; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRL, 0x88888888 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRH, 0x88888888 ); base = CYGHWR_HAL_STM32_GPIOC; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRL, 0x88888888 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRH, 0x88888888 ); // Set up GPIO lines for external bus base = CYGHWR_HAL_STM32_GPIOD; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRL, 0x44bb44bb ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRH, 0xbbbbbbbb ); base = CYGHWR_HAL_STM32_GPIOE; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRL, 0xbbbbb4bb ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRH, 0xbbbbbbbb ); base = CYGHWR_HAL_STM32_GPIOF; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRL, 0x44bbbbbb ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRH, 0xbbbb4444 ); base = CYGHWR_HAL_STM32_GPIOG; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRL, 0x44bbbbbb ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_CRH, 0x44444bb4 ); // Set up FSMC NOR/SRAM bank 2 for NOR Flash base = CYGHWR_HAL_STM32_FSMC; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR2, 0x00001059 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR2, 0x10000705 ); // Set up FSMC NOR/SRAM bank 3 for SRAM /* disabled by reille 2013.04.20 HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR3, 0x00001011 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR3, 0x00000200 ); */ // Added by reille 2013.04.20 HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR3, 0x00001011 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR3, 0x00000300 ); // Modified by gyr 2013.04.29 // HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR3, 0x00000301 ); // Added by reille 2013.04.29 // Set up FSMC NOR/SRAM bank 4 for LCD HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR4, 0x00001059 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR4, 0x10000502 ); #endif // Enable flash prefetch buffer and set latency to 2 wait states. { cyg_uint32 acr; base = CYGHWR_HAL_STM32_FLASH; HAL_READ_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr ); acr |= CYGHWR_HAL_STM32_FLASH_ACR_PRFTBE; acr |= CYGHWR_HAL_STM32_FLASH_ACR_LATENCY(2); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr ); } }
//========================================================================== // Setup up system clocks // void hal_start_clocks( void ) { CYG_ADDRESS sc = CYGHWR_HAL_LM3S_SC; cyg_uint32 rcc; #if defined(CYGHWR_HAL_CORTEXM_LM3S8XX_PLL) cyg_uint32 plllmis = CYGHWR_HAL_LM3S_SC_MISC_PLLLMIS; cyg_uint32 plllris = CYGHWR_HAL_LM3S_SC_RIS_PLLLRIS; volatile cyg_uint16 wait; #endif // At power up, the LM3S8xx is setup to use external oscillator. // The PLL is powered down and bypass. Same goes for the system // clock divider. // For JTAG cold restart, first we make sure the PLL and system // clock divider are bypassed, enable all clock source and shutdown // the PLL. HAL_READ_UINT32( sc + CYGHWR_HAL_LM3S_SC_RCC, rcc ); rcc &= ~( CYGHWR_HAL_LM3S_SC_RCC_USESYSDIV | CYGHWR_HAL_LM3S_SC_RCC_MOSCDIS | CYGHWR_HAL_LM3S_SC_RCC_IOSCDIS ); rcc |= CYGHWR_HAL_LM3S_SC_RCC_BYPASS; HAL_WRITE_UINT32( sc + CYGHWR_HAL_LM3S_SC_RCC, rcc ); rcc |= ( CYGHWR_HAL_LM3S_SC_RCC_PWRDN | CYGHWR_HAL_LM3S_SC_RCC_OEN ); HAL_WRITE_UINT32( sc + CYGHWR_HAL_LM3S_SC_RCC, rcc ); // PLL is setup if in use // // The XTAL frequency is configured. The PLL is powered and // its output is enable // Setup Clock Source rcc |= CYGHWR_HAL_CORTEXM_LM3S8XX_OSCSRC_FIELD; #if defined(CYGHWR_HAL_CORTEXM_LM3S8XX_PLL) // Clear PLL lock bit HAL_WRITE_UINT32( sc + CYGHWR_HAL_LM3S_SC_MISC, plllmis ); rcc &= ~( CYGHWR_HAL_LM3S_SC_RCC_XTAL_MASK | ( CYGHWR_HAL_LM3S_SC_RCC_PWRDN ) | ( CYGHWR_HAL_LM3S_SC_RCC_OEN ) ); rcc |= CYGHWR_HAL_CORTEXM_LM3S8XX_XTAL; #endif HAL_WRITE_UINT32( sc + CYGHWR_HAL_LM3S_SC_RCC, rcc ); // // Setup System Clock divider // #if CYGHWR_HAL_CORTEXM_LM3S8XX_SYSCLK_DIV != 1 // Use system clock divider rcc |= CYGHWR_HAL_LM3S_SC_RCC_USESYSDIV; // Clear system clock divider bits rcc &= ~CYGHWR_HAL_LM3S_SC_RCC_SYSDIV_MASK; // Configure divider rcc |= CYGHWR_HAL_CORTEXM_LM3S8XX_SC_RCC_SYSDIV_VAL; HAL_WRITE_UINT32( sc + CYGHWR_HAL_LM3S_SC_RCC, rcc ); #endif // Wait for PLL lock before feeding the clock to the // device #if defined(CYGHWR_HAL_CORTEXM_LM3S8XX_PLL) // Wait for PLL lock, potentially a dead lock plllris = 0; while ( 0 == ( plllris & CYGHWR_HAL_LM3S_SC_RIS_PLLLRIS ) ) { // Wait for ( wait = 0; wait < ( ( 2 ^ 16 ) - 1 ); wait++ ) HAL_READ_UINT32( sc + CYGHWR_HAL_LM3S_SC_RIS, plllris ); } // Clear bypass bit rcc &= ~CYGHWR_HAL_LM3S_SC_RCC_BYPASS; HAL_WRITE_UINT32( sc + CYGHWR_HAL_LM3S_SC_RCC, rcc ); #endif // // Disable clock source not in use // #if defined(CYGHWR_HAL_CORTEXM_LM3S8XX_CLOCK_EXT) rcc |= CYGHWR_HAL_LM3S_SC_RCC_IOSCDIS; #elif defined(CYGHWR_HAL_CORTEXM_LM3S8XX_CLOCK_INT) rcc |= CYGHWR_HAL_LM3S_SC_RCC_MOSCDIS; #endif HAL_WRITE_UINT32( sc + CYGHWR_HAL_LM3S_SC_RCC, rcc ); hal_cortexm_systick_clock = CYGHWR_HAL_CORTEXM_LM3S8XX_SYSCLK; hal_lm3s_sysclk = CYGHWR_HAL_CORTEXM_LM3S8XX_SYSCLK; }
/** * * QSPI bus initialization function * * @param qspi_bus - Driver handle * * @return none * *****************************************************************************/ static void qspi_xc7z_init_bus(cyg_qspi_xc7z_bus_t * qspi_bus) { entry_debug(); volatile cyg_uint32 reg; // Create and attach SPI interrupt object cyg_drv_interrupt_create(qspi_bus->interrupt_number, 4, (cyg_addrword_t)qspi_bus, qspi_xc7z_ISR, qspi_xc7z_DSR, &qspi_bus->qspi_interrupt_handle, &qspi_bus->qspi_interrupt); cyg_drv_interrupt_attach(qspi_bus->qspi_interrupt_handle); cyg_drv_interrupt_mask(qspi_bus->interrupt_number); // Init transfer mutex and condition cyg_drv_mutex_init(&qspi_bus->transfer_mx); cyg_drv_cond_init(&qspi_bus->transfer_cond, &qspi_bus->transfer_mx); // Init flags qspi_bus->transfer_end = true; qspi_bus->cs_up = false; // Unlock SLCR regs HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCR_UNLOCK_OFFSET, XSLCR_UNLOCK_KEY); // Enable clock to QSPI module HAL_READ_UINT32( XC7Z_SYS_CTRL_BASEADDR + XSLCRAPER_CLK_CTRL_OFFSET, reg); reg |= XSLCRAPER_CLK_CTRL_QSPI_EN; HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCRAPER_CLK_CTRL_OFFSET, reg); // Lock SLCR regs HAL_WRITE_UINT32(XC7Z_SYS_CTRL_BASEADDR + XSLCR_LOCK_OFFSET, XSLCR_LOCK_KEY); // Soft reset the SPI controller HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_ER_OFFSET, 0x00); //TODO changed, originally was just setting a value without reading HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, reg); reg &= (1 << 17); // preserve the reserved bit which is described as "do not modify" reg |= (1 << 31); HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, reg); // Disable linear mode HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_LQSPI_CR_OFFSET, 0x00); // Clear status HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, 0x7F); // Clear the RX FIFO HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, reg); while (reg & XQSPIPS_IXR_RXNEMPTY_MASK) { HAL_READ_UINT32(qspi_bus->base + XQSPIPS_RXD_OFFSET, reg); HAL_READ_UINT32(qspi_bus->base + XQSPIPS_SR_OFFSET, reg); } HAL_READ_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, reg); reg &= 0xFBFFFFFF; /* Set little endian mode of TX FIFO */ reg |= (XQSPIPS_CR_IFMODE_MASK | XQSPIPS_CR_MANSTRTEN_MASK | XQSPIPS_CR_SSFORCE_MASK | XQSPIPS_CR_SSCTRL_MASK | XQSPIPS_CR_DATA_SZ_MASK | XQSPIPS_CR_MSTREN_MASK); HAL_WRITE_UINT32(qspi_bus->base + XQSPIPS_CR_OFFSET, reg); // Configure SPI pins // All pins was configured in HAL // Call upper layer bus init CYG_SPI_BUS_COMMON_INIT(&qspi_bus->qspi_bus); }