예제 #1
0
BOOL I2C_Internal_Initialize()
{
    NATIVE_PROFILE_HAL_PROCESSOR_I2C();
    
    if (!(RCC->APB1ENR & RCC_APB1ENR_I2CxEN)) { // only once
        currentI2CXAction = NULL;
        currentI2CUnit = NULL;
        
        CPU_GPIO_DisablePin( I2Cx_SDA_Pin, RESISTOR_DISABLED, 0, GPIO_ALT_MODE_3 ); // open drain
        CPU_GPIO_DisablePin( I2Cx_SCL_Pin, RESISTOR_DISABLED, 0, GPIO_ALT_MODE_3 ); // open drain
        
        RCC->APB1ENR |= RCC_APB1ENR_I2CxEN; // enable I2C clock
        RCC->APB1RSTR = RCC_APB1RSTR_I2CxRST; // reset I2C peripheral
        RCC->APB1RSTR = 0;
        
        I2Cx->CR2 = SYSTEM_APB1_CLOCK_HZ / 1000000; // APB1 clock in MHz
        I2Cx->CCR = (SYSTEM_APB1_CLOCK_HZ / 1000 / 2 - 1) / 100 + 1; // 100KHz
        I2Cx->TRISE = SYSTEM_APB1_CLOCK_HZ / (1000 * 1000) + 1; // 1ns;
        I2Cx->OAR1 = 0x4000; // init address register
        
        I2Cx->CR1 = I2C_CR1_PE; // enable peripheral
        
        CPU_INTC_ActivateInterrupt(I2Cx_EV_IRQn, STM32_I2C_EV_Interrupt, 0);
        CPU_INTC_ActivateInterrupt(I2Cx_ER_IRQn, STM32_I2C_ER_Interrupt, 0);
    }
    
    return TRUE;
}
int AT91_EMAC_LWIP_Driver::Open(int index)
{
    /* Network interface variables */
    struct ip_addr ipaddr, subnetmask, gateway;
    struct netif *pNetIF;
    int len;
    const SOCK_NetworkConfiguration *iface;

    /* Apply network configuration */
    iface = &g_NetworkConfig.NetworkInterfaces[index];

    len = g_AT91_EMAC_NetIF.hwaddr_len;
    if(len == 0 || iface->macAddressLen < len)
    {
        len = iface->macAddressLen;
        g_AT91_EMAC_NetIF.hwaddr_len = len;
    }
    memcpy(g_AT91_EMAC_NetIF.hwaddr, iface->macAddressBuffer, len);

    if(0 == (iface->flags & SOCK_NETWORKCONFIGURATION_FLAGS_DHCP))
    {
        ipaddr.addr     = iface->ipaddr;
        gateway.addr    = iface->gateway;
        subnetmask.addr = iface->subnetmask;
    }
    else
    {
        /* Set network address variables - this will be set by either DHCP or when the configuration is applied */
        IP4_ADDR(&gateway, 0,0,0,0);
        IP4_ADDR(&ipaddr, 0,0,0,0);
        IP4_ADDR(&subnetmask, 255,255,255,0);
    }

    // PHY Power Up
    CPU_GPIO_EnableOutputPin(g_AT91_EMAC_LWIP_Config.PHY_PD_GPIO_Pin, FALSE);

    // Enable Interrupt
    CPU_INTC_ActivateInterrupt(AT91C_ID_EMAC, (HAL_CALLBACK_FPN)AT91_EMAC_LWIP_interrupt, &g_AT91_EMAC_NetIF);

    g_AT91_EMAC_NetIF.flags = NETIF_FLAG_IGMP | NETIF_FLAG_BROADCAST;

    pNetIF = netif_add( &g_AT91_EMAC_NetIF, &ipaddr, &subnetmask, &gateway, NULL, AT91_EMAC_ethhw_init, ethernet_input );

    netif_set_default( pNetIF );

    LWIP_STATUS_setorclear( LWIP_STATUS_LinkUp, 0 != dm9161_lwip_GetLinkStatus( ) );

    if (LWIP_STATUS_isset(LWIP_STATUS_LinkUp))
    {
        netif_set_link_up( pNetIF );
        netif_set_up     ( pNetIF );

        Network_PostEvent( NETWORK_EVENT_TYPE__AVAILABILITY_CHANGED, NETWORK_EVENT_FLAGS_IS_AVAILABLE );
    }

    /* Initialize the continuation routine for the driver interrupt and receive */    
    InitContinuations( pNetIF );

    return g_AT91_EMAC_NetIF.num;
}
예제 #3
0
BOOL LPC178X_I2C_Driver::Initialize()
{
#if 0
    LPC178X_I2C& I2C = LPC178X::I2C();
    
    g_LPC178X_I2C_Driver.m_currentXAction     = NULL;
    g_LPC178X_I2C_Driver.m_currentXActionUnit = NULL;

    CPU_GPIO_DisablePin( LPC178X_I2C::c_I2C_SDA, RESISTOR_DISABLED, 0, GPIO_ALT_MODE_1 );
    CPU_GPIO_DisablePin( LPC178X_I2C::c_I2C_SCL, RESISTOR_DISABLED, 0, GPIO_ALT_MODE_1 );

    CPU_INTC_ActivateInterrupt(NVIC_TO_INTC(I2C0_IRQn), ISR, NULL );

	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, ENABLE);

    /* Set I2C operation to default */
    I2C.I2CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC);



    // enable the I2c module
    I2C.I2CONSET  = LPC178X_I2C::I2EN;
    // set the Subordinate address
    I2C.I2ADR = 0x7E;
#endif
    return TRUE;
}
BOOL LPC24XX_TIMER_Driver::Initialize( UINT32 Timer, HAL_CALLBACK_FPN ISR, void* ISR_Param )
{
    ASSERT(Timer < c_MaxTimers);

    GLOBAL_LOCK(irq);

    if(g_LPC24XX_TIMER_Driver.m_configured[Timer] == TRUE) return FALSE;

    //--//

    if(ISR)
    {
        if(!CPU_INTC_ActivateInterrupt( LPC24XX_TIMER::getIntNo(Timer) , ISR, ISR_Param )) return FALSE;
    }

    LPC24XX_TIMER& TIMER = LPC24XX::TIMER( Timer );

    TIMER.TCR = LPC24XX_TIMER::TCR_TEN;

    //--//

    g_LPC24XX_TIMER_Driver.m_configured[Timer] = TRUE;

    return TRUE;
}
int LPC24XX_EMAC_Driver::Open()
{
    int use_default_multicast = 1;
    
    memset(&g_LPC24XX_EMAC_Driver.m_currentDhcpSession, 0, sizeof(g_LPC24XX_EMAC_Driver.m_currentDhcpSession));

    /* Open the interface first */
    g_LPC24XX_EMAC_Driver.m_interfaceNumber = xn_interface_open_config (LPC24XX_EMAC_DEVICE, 
                                                                        0,              /*  minor_number        */
                                                                        0,              /*  ioaddress           */
                                                                        0,              /*  irq value           */
                                                                        0               /*  mem_address)        */
                                                    );
    
    if (g_LPC24XX_EMAC_Driver.m_interfaceNumber == -1)
    {
        return -1;    
    }

    if (xn_interface_opt(g_LPC24XX_EMAC_Driver.m_interfaceNumber, 
                        IO_DEFAULT_MCAST,
                        (RTP_PFCCHAR)&use_default_multicast,
                        sizeof(int)) == -1)
    {
        /* Failed to set the default multicast interface */
        debug_printf("LPC24XX_EMAC_Driver::Open: Failed to set the default multicast interface\r\n");
    }
    
       
    /* Enable the INTERRUPT */                            
    CPU_INTC_ActivateInterrupt(LPC24XX_VIC::c_IRQ_INDEX_EMAC, LPC24XX_EMAC_interrupt, NULL);

    return g_LPC24XX_EMAC_Driver.m_interfaceNumber;    
}
예제 #6
0
// ---------------------------------------------------------------------------
static UINT8 GPIO_InitIRQ(GPIO_PIN Pin, GPIO_INTERRUPT_SERVICE_ROUTINE ISR, void* Param)
{
    UINT8 ch = g_channel; // ToDo: Search for empty one so ch != g_channel
    UINT8 port = LPC43XX_GPIO_PORT(Pin), bit = LPC43XX_GPIO_PIN(Pin);
    GPIO_IRQ_T *obj;

    // Set IRQ data
    *obj = gpio_irq[ch];
    obj->ch = g_channel;
    obj->pin = Pin;
    obj->isr = ISR;
    obj->param = Param;

	  // Clear rising and falling edge detection
    //pmask = (1 << g_channel);
    //LPC_GPIO_PIN_INT->IST = pmask;

    // Set SCU
    if (g_channel < 4) {
        LPC_SCU->PINTSEL0 &= ~(0xFF << (port << 3));
        LPC_SCU->PINTSEL0 |= (((port << 5) | bit) << (g_channel << 3));
    } else {
        LPC_SCU->PINTSEL1 &= ~(0xFF << ((port - 4) << 3));
        LPC_SCU->PINTSEL1 |= (((port << 5) | bit) << ((g_channel - 4) << 3));
    }
	
    CPU_INTC_ActivateInterrupt((IRQn_Type)(PIN_INT0_IRQn + g_channel), GPIO_IRQHandler, (void*) obj);

    // Increment channel number
    g_channel++;
    g_channel %= TOTAL_GPIO_INT;

    return obj->ch;
}
BOOL AT91_TSADCC_Driver::Initialize(GPIO_INTERRUPT_SERVICE_ROUTINE touchIsrProc)
{
	UINT32 i;
	UINT32 dwValue;
	struct AT91S_TSADC *pTSADC = (struct AT91S_TSADC *)AT91C_BASE_TSADCC;
	AT91_PMC &pmc = AT91::PMC();
	
	/* Selected as TSADCC pins */
    for(i = 0; i < NO_PIN; i++)
    {
        CPU_GPIO_DisablePin( c_TSADCC[i], RESISTOR_DISABLED, 0, GPIO_ALT_MODE_1);
    }
	
	pmc.EnablePeriphClock(AT91C_ID_TSADCC);
	
	dwValue = (SYSTEM_PERIPHERAL_CLOCK_HZ/(ADC_CLOCK * 2)) - 1;
	if(dwValue > 0X3F)	// Saturation
		dwValue = 0x3F;
	
	//debug_printf("dwValue :%d\r\n", dwValue);
	pTSADC->TSADC_MR = (AT91C_TSADC_TSAMOD_TS_ONLY_MODE |
					   AT91C_TSADC_PENDET |
					   (dwValue << 8) |
					   AT91C_TSADC_SLEEP |
					   STARTUP_TIME << 16 |
					   PEN_DEBOUNCE_TIME << 28);
					   
	pTSADC->TSADC_TSR = SAMPLE_AND_HOLD_TIME << 24;
	
	pTSADC->TSADC_TRGR = AT91C_TSADC_TRGMOD_NO_TRIGGER;
	
	pTSADC->TSADC_IER = AT91C_TSADC_PENCNT;
	
	CPU_INTC_ActivateInterrupt( AT91C_ID_TSADCC, TSADCC_ISR, NULL);
	
	for (i = 0; i<SAMPLE_NB; i++)
	{
		g_AT91_TSADCC_Driver.m_stiX_Samples[i] = 0;
		g_AT91_TSADCC_Driver.m_stiY_Samples[i] = 0;
	}
	g_AT91_TSADCC_Driver.m_sdwSampleIndex = 0;
	g_AT91_TSADCC_Driver.m_sdwSampleNo = 0;
	g_AT91_TSADCC_Driver.m_siX_SampleSum = 0;
	g_AT91_TSADCC_Driver.m_siY_SampleSum = 0;
	g_AT91_TSADCC_Driver.m_TipState = 0;
	g_AT91_TSADCC_Driver.m_UnCalX = 0;
	g_AT91_TSADCC_Driver.m_UnCalY = 0;
	
	g_AT91_TSADCC_Driver.m_touchIsrProc = touchIsrProc;
	
	//debug_printf("AT91_TSADCC_Driver::Initialize called\r\n");
	return TRUE;
}
//Initialize the specified channel. Reserve A and B pins (not the IO pins)
//countMode X1=1, X2=2, X4=3
HRESULT	QED_Initialize		(int channel, int countMode) {
	if (channel != 0)
		return CLR_E_INVALID_PARAMETER;
	if (countMode < 1 || countMode > 3)
		return CLR_E_INVALID_PARAMETER;
	//Reserve PA0 and PA1
	if (CPU_GPIO_ReservePin(0, TRUE) == false) 
		return CLR_E_PIN_UNAVAILABLE;
	if (CPU_GPIO_ReservePin(1, TRUE) == false) 
		return CLR_E_PIN_UNAVAILABLE;
	//Power port A (should be already done in bootstrap) and TIM2
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
	RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
	//PA0 and PA1 mode alternate: 10b
	GPIOA->MODER &= ~(GPIO_MODER_MODER1 | GPIO_MODER_MODER0);
	GPIOA->MODER |= (GPIO_MODER_MODER1_1 | GPIO_MODER_MODER0_1);
	//Alternate function AF1 : TIM2 input for PA1 and PA0
	GPIOA->AFR[0] &= ~0x000000FF;
	GPIOA->AFR[0] |= 0x00000011;
	//pull up
	GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR0 | GPIO_PUPDR_PUPDR1);
	GPIOA->PUPDR |= (GPIO_PUPDR_PUPDR0_0 | GPIO_PUPDR_PUPDR1_0);
	TIM2->CR2 = 0;
	//external clock enable
	TIM2->SMCR |= TIM_SMCR_ECE;
	//Encoder X mode count 
	TIM2->SMCR &= ~TIM_SMCR_SMS;
	TIM2->SMCR |= countMode;
	//if (countMode == 3)
	//	TIM2->SMCR |= TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0;	//X4
	//else 
	//	TIM2->SMCR |= TIM_SMCR_SMS_1;	//X2 on PA0
	//filter N=8
	TIM2->SMCR &= ~TIM_SMCR_ETF;
	TIM2->SMCR |= TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0;
	//no polarity invertion, rising edge
	TIM2->CCER = 0;
	//Count up to 32bits
	TIM2->ARR = 0xFFFFFFFF;

	for (int IOIndex = 0; IOIndex < 2; IOIndex++) {
		g_completion[IOIndex].InitializeForISR(&PulseCompletionHandler, (void*)IOIndex);
		g_pulseLength[IOIndex] = 0;
		g_IOStatus[IOIndex] = IOStatus_None; 
	}
	//activate interrupt and enable counter
	CPU_INTC_ActivateInterrupt(TIM2_IRQn, STM32F4_TIM2_Interrupt, 0);
	TIM2->CR1 |= TIM_CR1_CEN;

	return S_OK;
}
예제 #9
0
BOOL AT91_TIMER_Driver::Initialize( UINT32 timer, BOOL freeRunning, UINT32 clkSource, HAL_CALLBACK_FPN ISR, void* ISR_Param )
{
    ASSERT(timer < AT91_MAX_TIMER);

    GLOBAL_LOCK(irq);

    if(g_AT91_TIMER_Driver.m_descriptors[timer].configured == TRUE) return FALSE;

    g_AT91_TIMER_Driver.m_descriptors[timer].isr = ISR;
    g_AT91_TIMER_Driver.m_descriptors[timer].arg = ISR_Param;

    //--//

    if(ISR)
    { 
        if(!CPU_INTC_ActivateInterrupt( AT91C_ID_TC0 + timer, ISR_TIMER, (void*)timer )) return FALSE;
    }

    {
        AT91_TC &tc = AT91::TIMER(timer);


        // First, enable the clock of the TIMER
        AT91_PMC &pmc = AT91::PMC();
        pmc.PMC_PCER = (1 << (AT91C_ID_TC0+timer));

        // Disable the clock and the interrupts
        tc.TC_CCR = AT91_TC::TC_CLKDIS;
        tc.TC_IDR = 0xFFFFFFFF;

        // Clear status bit
        //(void) tc.TC_SR;
        ReadStatusRegister = tc.TC_SR;

        // Set the Mode of the timer Counter
        if( freeRunning == TRUE )
            tc.TC_CMR = (clkSource);
        else
            tc.TC_CMR = (AT91_TC::TC_CPCTRG | clkSource);
            
        // Enable Interrupt (Compare RC)
        tc.TC_IER = AT91_TC::TC_CPCS;

        // Enable the clock
        tc.TC_CCR = (AT91_TC::TC_CLKEN | AT91_TC::TC_SWTRG);
    }

    g_AT91_TIMER_Driver.m_descriptors[timer].configured = TRUE;

    return TRUE;
}
int STM32F4_ETH_LWIP_Driver::Open(int index)
{
    /* Network interface variables */
    struct ip_addr ipaddr, subnetmask, gateway;
    struct netif *pNetIF;
    int len;
    const SOCK_NetworkConfiguration *iface;

    EthernetPrepareZero();
    
    /* Enable Phy Powerdown on Deepsleep */
    STM32F4_SetPowerHandlers(EthernetDeepSleep, EthernetWakeUp);
    
    /* Apply network configuration */
    iface = &g_NetworkConfig.NetworkInterfaces[index];
    
    len = g_STM32F4_ETH_NetIF.hwaddr_len;
    if (len == 0 || iface->macAddressLen < len)
    {
        len = iface->macAddressLen;
        g_STM32F4_ETH_NetIF.hwaddr_len = len;
    }
    memcpy(g_STM32F4_ETH_NetIF.hwaddr, iface->macAddressBuffer, len);
    
    ipaddr.addr = iface->ipaddr;
    gateway.addr = iface->gateway;
    subnetmask.addr = iface->subnetmask;
      
    pNetIF = netif_add( &g_STM32F4_ETH_NetIF, &ipaddr, &subnetmask, &gateway, NULL, STM32F4_ETH_ethhw_init, ethernet_input );
    
    CPU_INTC_ActivateInterrupt(ETH_IRQn, (HAL_CALLBACK_FPN)STM32F4_ETH_LWIP_interrupt, &g_STM32F4_ETH_NetIF);
    
    netif_set_default( pNetIF );

    if (LwipNetworkStatus)
    {
        netif_set_up( pNetIF );
    }
    else
    {
        netif_set_down( pNetIF);
    }
    
    /* Initialize the continuation routine for the driver interrupt and receive */    
    InitContinuations( pNetIF );
    
    /* Return LWIP's net interface number */
    return g_STM32F4_ETH_NetIF.num;    
}
예제 #11
0
// ---------------------------------------------------------------------------
BOOL HAL_Time_Initialize()
{
    g_lastCount = 0;
    g_nextEvent = 0x0000FFFFFFFFFFFF;

    SYSTIMER->CTCR = 0x0; // Set timer mode
    SYSTIMER->TCR = 0x2; // Reset timer

    // Set prescaler for a microsecond timer (1 MHz -> 1 us ticks)
    SYSTIMER->PR = (SYSTEM_CLOCK_HZ / ONE_MHZ) - 1;
    SYSTIMER->TCR = 0x1; // Enable timer

    CPU_INTC_ActivateInterrupt(SYSTIMER_IRQn, systimer_handler, 0);

    return TRUE;
}
예제 #12
0
int AT91_EMAC_LWIP_Driver::Open(int index)
{
    /* Network interface variables */
    struct ip_addr ipaddr, subnetmask, gateway;
    struct netif *pNetIF;
    int len;
    const SOCK_NetworkConfiguration *iface;

    /* Apply network configuration */
    iface = &g_NetworkConfig.NetworkInterfaces[index];

    len = g_AT91_EMAC_NetIF.hwaddr_len;
    if(len == 0 || iface->macAddressLen < len)
    {
        len = iface->macAddressLen;
        g_AT91_EMAC_NetIF.hwaddr_len = len;
    }
    memcpy(g_AT91_EMAC_NetIF.hwaddr, iface->macAddressBuffer, len);

    ipaddr.addr = iface->ipaddr;
    gateway.addr = iface->gateway;
    subnetmask.addr = iface->subnetmask;

    // PHY Power Up
    CPU_GPIO_EnableOutputPin(g_AT91_EMAC_LWIP_Config.PHY_PD_GPIO_Pin, FALSE);

    // Enable Interrupt
    CPU_INTC_ActivateInterrupt(AT91C_ID_EMAC, (HAL_CALLBACK_FPN)AT91_EMAC_LWIP_interrupt, &g_AT91_EMAC_NetIF);

    /* Initialize the continuation routine for the driver interrupt and receive */    
    InitContinuations( pNetIF );

    pNetIF = netif_add( &g_AT91_EMAC_NetIF, &ipaddr, &subnetmask, &gateway, NULL, AT91_EMAC_ethhw_init, ethernet_input );

    netif_set_default( pNetIF );

    LwipNetworkStatus = dm9161_lwip_GetLinkStatus( );
    if (LwipNetworkStatus)
    {
        netif_set_up( pNetIF );
    }
    /* Initialize the continuation routine for the driver interrupt and receive */    
    InitContinuations( pNetIF );

    return g_AT91_EMAC_NetIF.num;
}
BOOL HAL_Time_Initialize()
{
    g_nextEvent = 0xFFFFFFFFFFFF; // never
    
    // enable timer 2-4 clocks
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN | RCC_APB1ENR_TIM4EN;
    
    // timer2
    TIM2->CR1 = TIM_CR1_URS;
    TIM2->CR2 = TIM_CR2_MMS_1; // master mode selection = update event
    TIM2->SMCR = 0; // TS = 000, SMS = 000, internal clock
    TIM2->DIER = TIM_DIER_CC1IE; // enable compare1 interrupt
    TIM2->CCMR1 = 0; // compare, no outputs
    TIM2->CCMR2 = 0; // compare, no outputs
    TIM2->PSC = (TIM2CLK_HZ / SLOW_CLOCKS_PER_SECOND) - 1; // prescaler to 1MHz
    TIM2->CCR1 = 0;
    TIM2->ARR = 0xFFFF;
    TIM2->EGR = TIM_EGR_UG; // enforce first update
    
    // timer3
    TIM3->CR1 = TIM_CR1_URS;
    TIM3->CR2 = TIM_CR2_MMS_1; // master mode selection = update event
    TIM3->SMCR = TIM_SMCR_TS_0 // TS = 001, clock = timer2 update
                 | TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_2; // SMS = 111
    TIM3->DIER = 0; // no interrupt
    TIM3->PSC = 0;  // no prescaler
    TIM3->ARR = 0xFFFF;
    TIM3->EGR = TIM_EGR_UG; // enforce first update
    
    // timer4
    TIM4->CR1 = TIM_CR1_URS;
    TIM4->CR2 = 0;
    TIM4->SMCR = TIM_SMCR_TS_1 // TS = 010, clock = timer3 update
                 | TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_2; // SMS = 111
    TIM4->DIER = 0; // no interrupt
    TIM4->PSC = 0;  // no prescaler
    TIM4->ARR = 0xFFFF;
    TIM4->EGR = TIM_EGR_UG; // enforce first update
    
    TIM4->CR1 |= TIM_CR1_CEN; // enable timers
    TIM3->CR1 |= TIM_CR1_CEN;
    TIM2->CR1 |= TIM_CR1_CEN;
    
    return CPU_INTC_ActivateInterrupt(TIM2_IRQn, Timer_Interrupt, 0);
}
예제 #14
0
BOOL hijackISRs()
{
    for(int irqIndex=0; irqIndex < 32; irqIndex++)
    {
        IRQ_INDEX_TEST[irqIndex] = irqIndex;
        if /*leave untouched ISRs needed for testing*/
        (
            irqIndex == LPC24XX_TIMER::getIntNo(LPC24XX_DAC::Timer)||
            irqIndex == LPC24XX_TIMER::getIntNo(LPC24XX_Driver::c_SystemTime_Timer)/*||
            irqIndex == LPC24XX_VIC::c_IRQ_INDEX_UART2 ||
            irqIndex == LPC24XX_VIC::c_IRQ_INDEX_DBG_COM_RX*/||
            irqIndex == LPC24XX_VIC::c_IRQ_INDEX_DBG_COM_TX
        )
            break;
        if(!CPU_INTC_ActivateInterrupt( irqIndex , hijackingISR, (void*)&(IRQ_INDEX_TEST[irqIndex]) )) return FALSE;
    }
    return true;
}
BOOL HAL_Time_Initialize()
{
    g_nextEvent = 0xFFFFFFFFFFFF; // never
    
    // enable timer clocks
#ifdef RCC_APB1ENR_TIM_16_EN
    RCC->APB1ENR |= RCC_APB1ENR_TIM_32_EN | RCC_APB1ENR_TIM_16_EN;
#else
    RCC->APB1ENR |= RCC_APB1ENR_TIM_32_EN;
    RCC->APB2ENR |= RCC_APB2ENR_TIM_16_EN;
#endif

    // configure jtag debug support
    DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM_32_STOP;
    
    // 32 bit timer (lower bits)
    TIM_32->CR1 = TIM_CR1_URS;
    TIM_32->CR2 = TIM_CR2_MMS_1; // master mode selection = update event
    TIM_32->SMCR = 0; // TS = 000, SMS = 000, internal clock
    TIM_32->DIER = TIM_DIER_CC1IE; // enable compare1 interrupt
    TIM_32->CCMR1 = 0; // compare, no outputs
    TIM_32->CCMR2 = 0; // compare, no outputs
    TIM_32->PSC = (TIM_CLK_HZ / SLOW_CLOCKS_PER_SECOND) - 1; // prescaler to 1MHz
    TIM_32->CCR1 = 0;
    TIM_32->ARR = 0xFFFFFFFF; // 32 bit counter
    TIM_32->EGR = TIM_EGR_UG; // enforce first update

    // 16 bit timer (upper bits)
    TIM_16->CR1 = TIM_CR1_URS;
    TIM_16->CR2 = 0;
    TIM_16->SMCR = TIM_SMCR_TS_BITS // clock = trigger = timer_32 update
                 | TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_2; // SMS = 111
    TIM_16->DIER = 0; // no interrupt
    TIM_16->PSC = 0;  // no prescaler
    TIM_16->ARR = 0xFFFF; // 16 bit counter
    TIM_16->EGR = TIM_EGR_UG; // enforce first update
    
    TIM_16->CR1 |= TIM_CR1_CEN; // enable timers
    TIM_32->CR1 |= TIM_CR1_CEN;
    
    return CPU_INTC_ActivateInterrupt(TIM_32_IRQn, Timer_Interrupt, 0);
}
예제 #16
0
BOOL LPC24XX_DAC_Driver::On()
{
	if(g_LPC24XX_DAC_Driver.SampleTimeInCycles == 0) return FALSE;
	
	ASSERT(LPC24XX_DAC::Timer < LPC24XX_TIMER_Driver::c_MaxTimers);

    GLOBAL_LOCK(irq);

    if(g_LPC24XX_TIMER_Driver.m_configured[LPC24XX_DAC::Timer] == TRUE) return FALSE;

    //--//
	
	//rise IRQ priority to the highest one. this guarantees delay < execution time of the longest ISR in the system
	LPC24XX_VIC& VIC = LPC24XX::VIC();	
	VIC.VECTPRIORITY[LPC24XX_TIMER::getIntNo(LPC24XX_DAC::Timer)] = 0;

    if(!CPU_INTC_ActivateInterrupt( LPC24XX_TIMER::getIntNo(LPC24XX_DAC::Timer) , LPC24XX_DAC_Driver::ISR, NULL )) return FALSE;
    

    LPC24XX_TIMER& TIMER = LPC24XX::TIMER(LPC24XX_DAC::Timer);

	//Reset and Enable timer
	TIMER.TCR = 0x00000002;
    TIMER.TCR = LPC24XX_TIMER::TCR_TEN;
	
	//set prescaler to 0, we only need very short time intervals
	TIMER.PR = 0x00000000;
	
	//load MATCH REGISTER with TARGET time (expressed in cycles, since PR=0)
	TIMER.MR0 = g_LPC24XX_DAC_Driver.SampleTimeInCycles;
		
	//set MatchControlRegister to generate INTR (bit 0) on MR0 == TC and reset timer (bit 1) immediately 
	//this way the IRQ will be generated every X us, regardless of when the ISR for the last one is actually executed
	
	TIMER.MCR = 0x00000003; 
	
    //--//

    g_LPC24XX_TIMER_Driver.m_configured[LPC24XX_DAC::Timer] = TRUE;

    return TRUE;
}
예제 #17
0
int LPC24XX_EMAC_LWIP_Driver::Open(int index)
{    
    /* Network interface variables */
    struct ip_addr ipaddr, subnetmask, gateway;
    struct netif *pNetIF;
    int len;
    const SOCK_NetworkConfiguration *iface;

    /* Apply network configuration */
    iface = &g_NetworkConfig.NetworkInterfaces[index];

    len = g_LPC24XX_EMAC_NetIF.hwaddr_len;
    if(len == 0 || iface->macAddressLen < len)
    {
        len = iface->macAddressLen;
        g_LPC24XX_EMAC_NetIF.hwaddr_len = len;
    }
    memcpy(g_LPC24XX_EMAC_NetIF.hwaddr, iface->macAddressBuffer, len);

    ipaddr.addr = iface->ipaddr;
    gateway.addr = iface->gateway;
    subnetmask.addr = iface->subnetmask;

    pNetIF = netif_add( &g_LPC24XX_EMAC_NetIF, &ipaddr, &subnetmask, &gateway, NULL, lpc24xx_ethhw_init, ethernet_input );
       
    /* Enable the INTERRUPT */                            
    CPU_INTC_ActivateInterrupt(LPC24XX_VIC::c_IRQ_INDEX_EMAC, (HAL_CALLBACK_FPN)LPC24XX_EMAC_lwip_interrupt, &g_LPC24XX_EMAC_NetIF);

    netif_set_default( pNetIF );
    LwipNetworkStatus = ENET_PHY_lwip_get_link_status( );
    if (LwipNetworkStatus)
    {
        netif_set_up( pNetIF );
    }
    /* Initialize the continuation routine for the driver interrupt and receive */    
    InitContinuations( pNetIF );

    // Return LWIP's net interface number
    return g_LPC24XX_EMAC_NetIF.num;    
}
예제 #18
0
///////////////////////////////////////////////////////////////////////////////
//  Initialize
///////////////////////////////////////////////////////////////////////////////
BOOL LPC24XX_GPIO_Driver::Initialize()
{
    int i;
    UINT32 port;
    LPC24XX_GPIO& GPIO = LPC24XX::GPIO();

    /* Enable fast GPIO on Port 0 & 1 */
    LPC24XX::SYSCON().SCS |= LPC24XX_SYSCON::HS_IO;

    for (port=0; port < c_MaxPins; port++)
    {
        g_LPC24XX_GPIO_Driver.m_PinReservationInfo[port] = FALSE;
    }

    // initialize the interrupt information
    {
        PIN_ISR_DESCRIPTOR* pinIsr = g_LPC24XX_GPIO_Driver.m_PinIsr;

        for(i = 0; i < c_MaxPins; i++)
        {
            pinIsr->m_pin     = i;
            pinIsr->m_intEdge = GPIO_INT_NONE;
            pinIsr->m_isr     = LPC24XX_GPIO_Driver::STUB_ISRVector;
            pinIsr->m_param   = NULL;
            
            pinIsr->m_completion.Initialize( );
            pinIsr->m_completion.InitializeForISR( &PIN_ISR_DESCRIPTOR::Fire, pinIsr );
            
            pinIsr++;
        }
    }

    
    // register interrupt handler (GPIO uses EINT3)
    if(!CPU_INTC_ActivateInterrupt( LPC24XX_VIC::c_IRQ_INDEX_EINT3, GPIO_ISR, NULL )) return FALSE;
    
    return TRUE;
}
int AT91_EMAC_Driver::Open()
{
    int use_default_multicast;

    memset(&g_AT91_EMAC_Driver.m_currentDhcpSession, 0, sizeof(g_AT91_EMAC_Driver.m_currentDhcpSession));

    // PHY Power Up
    CPU_GPIO_EnableOutputPin(g_AT91_EMAC_Config.PHY_PD_GPIO_Pin, FALSE);

     /* Open the interface first */
    g_AT91_EMAC_Driver.m_interfaceNumber = xn_interface_open_config(AT91EMAC_DEVICE, 
                                                    0,              /*  minor_number        */
                                                    0,              /*  ioaddress           */
                                                    0,              /*  irq value           */
                                                    0               /*  mem_address)        */
                                                    );

    if (g_AT91_EMAC_Driver.m_interfaceNumber == -1)
    {
        return -1;    
    }
    
    use_default_multicast = 1;
    if (xn_interface_opt(g_AT91_EMAC_Driver.m_interfaceNumber, 
                        IO_DEFAULT_MCAST,
                        (RTP_PFCCHAR)&use_default_multicast,
                        sizeof(int)) == -1)
    {
        /* Failed to set the default multicast interface */
        debug_printf("EMAC: Failed to set the default multicast interface\r\n");
    }

    CPU_INTC_ActivateInterrupt(AT91C_ID_EMAC, AT91_EMAC_interrupt, NULL);

    return g_AT91_EMAC_Driver.m_interfaceNumber;
}
BOOL LPC22XX_TIMER_Driver::Initialize( UINT32 Timer, HAL_CALLBACK_FPN ISR, void* ISR_Param )
{
    ASSERT(Timer < c_MaxTimers);

    GLOBAL_LOCK(irq);

    if(g_LPC22XX_TIMER_Driver.m_configured[Timer] == TRUE) return FALSE;

    //--//

    if(ISR)
    {
		UINT32 irq;

		if(Timer)
		{
			irq = LPC22XX_VIC::c_IRQ_INDEX_TIMER1;
		}
		else
		{
			irq = LPC22XX_VIC::c_IRQ_INDEX_TIMER0;
		}

        if(!CPU_INTC_ActivateInterrupt( irq, ISR, ISR_Param )) return FALSE;
    }

    LPC22XX_TIMER& TIMER = LPC22XX::TIMER( Timer );

    TIMER.TCR = LPC22XX_TIMER::TCR_TEN;

    //--//

    g_LPC22XX_TIMER_Driver.m_configured[Timer] = TRUE;

    return TRUE;
}
예제 #21
0
HRESULT PXA271_USB_Driver::Initialize( int Controller )
{
    int endpointsUsed = 0;
    const USB_ENDPOINT_DESCRIPTOR  *ep    = NULL;
    const USB_INTERFACE_DESCRIPTOR *itfc  = NULL;
    USB_CONTROLLER_STATE &State = UsbControllerState[0];

    ASSERT( Controller == 0 );

    GLOBAL_LOCK(irq);

    PXA271_USB& USB = PXA271::USB();

    // make sure clock is enabled
    PXA271::CLKMNGR().CKEN |= PXA271_CLOCK_MANAGER::CKEN__USB_CLIENT_48MHZ;

    // Enable the only interrupt
    CPU_INTC_ActivateInterrupt( PXA271_AITC::c_IRQ_INDEX_USB_CLIENT, Global_ISR, NULL );

    for( int i = 0; i < c_Used_Endpoints; i++ )
        EndpointInit[i].word = 0;       // All useable endpoints initialize to unused

    // For all endpoints in the USB configuration
    while( USB_NextEndpoint( &State, ep, itfc) )
    {
        UINT8 endpointNum   = ep->bEndpointAddress & 0x7F;
        UINT16 endpointSize = ep->wMaxPacketSize;
        
        // Check interface and endpoint numbers against hardware capability
        if( endpointNum >= c_Used_Endpoints || itfc->bInterfaceNumber > 7 )
            return S_FALSE;
        
        EndpointInit[endpointNum].bits.EN   = endpointNum;
        EndpointInit[endpointNum].bits.ED   = (ep->bEndpointAddress & 0x80) ? 1 : 0;
        EndpointInit[endpointNum].bits.IN   = itfc->bInterfaceNumber;
        EndpointInit[endpointNum].bits.ET   = ep->bmAttributes & 0x03;
        EndpointInit[endpointNum].bits.CN   = 1;        // Always only 1 configuration = 1
        EndpointInit[endpointNum].bits.AISN = 0;        // No alternate interfaces
        EndpointInit[endpointNum].bits.EE   = 1;        // Enable this endpoint

        // Set the maximum size of the endpoint hardware FIFO
        if( (ep->bmAttributes & 0x03) == USB_ENDPOINT_ATTRIBUTE_BULK )
        {
            // If the endpoint maximum size in the configuration list is bogus
            if( endpointSize != 8 && endpointSize != 16 && endpointSize != 32 && endpointSize != 64 )
                return S_FALSE;
            EndpointInit[endpointNum].bits.MPS = endpointSize;
            State.MaxPacketSize[endpointNum]   = endpointSize;
        }
        else if( (ep->bmAttributes & 0x03) == USB_ENDPOINT_ATTRIBUTE_INTERRUPT )
        {
            if( endpointSize == 0 || endpointSize > 64 )
                return S_FALSE;
            EndpointInit[endpointNum].bits.MPS = endpointSize;
            State.MaxPacketSize[endpointNum]   = endpointSize;
        }
        else        // Isochronous endpoint
        {
            if( endpointSize > 64 )
                endpointSize = 64;
            EndpointInit[endpointNum].bits.MPS = endpointSize;
            State.MaxPacketSize[endpointNum]   = endpointSize;
        }

        // Since endpoint 0 is only used for control, there is never a need to allocate a buffer for it
        // In fact State.Queues[0] is always NULL - it is a cheap placeholder to make the queueIndex = endpointIndex
        QueueBuffers[endpointNum-1].Initialize();                       // Clear queue before use
        State.Queues[endpointNum] = &QueueBuffers[endpointNum-1];       // Attach queue to endpoint

        // Set up direction information
        if( EndpointInit[endpointNum].bits.ED )         // If transmit endpoint
        {
            EndpointInit[endpointNum].bits.DE = 1;      // Only transmit is double buffered
            State.IsTxQueue[endpointNum]      = TRUE;
        }
        else        // If receive endpoint
        {
            EndpointInit[endpointNum].bits.DE = 0;
            State.IsTxQueue[endpointNum]      = FALSE;
        }
        endpointsUsed++;
    }
    
    // If no endpoints were initialized, something is seriously wrong with the configuration list
    if( 0 == endpointsUsed )
    {
        CPU_INTC_DeactivateInterrupt( PXA271_AITC::c_IRQ_INDEX_USB_CLIENT );
        return S_FALSE;
    }

    g_PXA271_USB_Driver.pUsbControllerState  = &State;
    g_PXA271_USB_Driver.PinsProtected        = TRUE;

    State.EndpointStatus = &g_PXA271_USB_Driver.EndpointStatus[0];
    State.EndpointCount  = c_Used_Endpoints;
    //State->DeviceStatus   = USB_STATUS_DEVICE_SELF_POWERED;
    State.PacketSize     = c_default_ctrl_packet_size;
    
    State.FirstGetDescriptor = TRUE;

    ProtectPins( Controller, FALSE );

    return S_OK;
}
BOOL LPC22XX_USART_Driver::Initialize( int ComPortNum, int BaudRate, int Parity, int DataBits, int StopBits, int FlowValue )
{

    GLOBAL_LOCK(irq);
    LPC22XX_USART& USARTC = LPC22XX::UART(ComPortNum);
    UINT32 divisor;  
    BOOL   fRet = TRUE;
    
    
    ASSERT(LPC22XX_USART_Driver::IsValidPortNum(ComPortNum));
    
    //calculate the divisor that's required.
    divisor     =  ((LPC22XX_USART::c_ClockRate / (BaudRate * 16)));
    
    // CWS: Disable interrupts
    USARTC.UART_LCR = 0; // prepare to Init UART
    USARTC.SEL2.IER.UART_IER &= ~(LPC22XX_USART::UART_IER_INTR_ALL_SET);          // Disable all UART interrupts
    /* CWS: Set baud rate to baudRate bps */
    USARTC.UART_LCR|= LPC22XX_USART::UART_LCR_DLAB;                                          // prepare to access Divisor
    USARTC.SEL1.DLL.UART_DLL = divisor & 0xFF;      //GET_LSB(divisor);                                                      // Set baudrate.
    USARTC.SEL2.DLM.UART_DLM = (divisor>>8) & 0xFF; // GET_MSB(divisor);
    USARTC.UART_LCR&= ~LPC22XX_USART::UART_LCR_DLAB;                                              // prepare to access RBR, THR, IER
    // CWS: Set port for 8 bit, 1 stop, no parity  

    // DataBit range 5-8
    if(5 <= DataBits && DataBits <= 8)
    {
        SET_BITS(USARTC.UART_LCR,
                 LPC22XX_USART::UART_LCR_WLS_shift,
                 LPC22XX_USART::UART_LCR_WLS_mask,
                 DataBits-5);
    }
    else
    {   // not supported
        fRet = FALSE;

        // set up 8 data bits incase return value is ignored
        SET_BITS(USARTC.UART_LCR,
                 LPC22XX_USART::UART_LCR_WLS_shift,
                 LPC22XX_USART::UART_LCR_WLS_mask,
                 LPC22XX_USART::UART_LCR_WLS_8_BITS);
    }

    switch(StopBits)
    {
        case USART_STOP_BITS_ONE:
            USARTC.UART_LCR |= LPC22XX_USART::UART_LCR_NSB_1_STOPBITS;
            break;
        case USART_STOP_BITS_ONEPOINTFIVE:
            USARTC.UART_LCR |= LPC22XX_USART::UART_LCR_NSB_15_STOPBITS;
            break;

        // not supported
        case USART_STOP_BITS_NONE:
        default:
            fRet = FALSE;
            break;
    }

    switch(Parity)
    {
        case USART_PARITY_SPACE:
            USARTC.UART_LCR |= LPC22XX_USART::UART_LCR_SPE;
        case USART_PARITY_EVEN:
            USARTC.UART_LCR |= (LPC22XX_USART::UART_LCR_EPE | LPC22XX_USART::UART_LCR_PBE);
            break;

        case USART_PARITY_MARK:
            USARTC.UART_LCR |= LPC22XX_USART::UART_LCR_SPE;
        case USART_PARITY_ODD:
            USARTC.UART_LCR |= LPC22XX_USART::UART_LCR_PBE;
            break;       

        case USART_PARITY_NONE:
            USARTC.UART_LCR &= ~LPC22XX_USART::UART_LCR_PBE;
            break;
            
        // not supported
        default:
            fRet = FALSE;
            break;
    }
    
    // CWS: Set the RX FIFO trigger level (to 8 bytes), reset RX, TX FIFO 
    USARTC.SEL3.FCR.UART_FCR =  (LPC22XX_USART::UART_FCR_RFITL_01>> LPC22XX_USART::UART_FCR_RFITL_shift )  |
                                LPC22XX_USART::UART_FCR_TFR      | 
                                LPC22XX_USART::UART_FCR_RFR      |
                                LPC22XX_USART::UART_FCR_FME;

    ProtectPins( ComPortNum, FALSE );

    CPU_INTC_ActivateInterrupt( LPC22XX_USART::getIntNo(ComPortNum),
                                UART_IntHandler,
                                (void *)ComPortNum);    
    
    return fRet;
}
예제 #23
0
//Initialize USB Host
// USB OTG Full Speed is controller 0
// USB OTG High Speed is controller 1
BOOL USBH_Initialize( int Controller ) {
	CPU_GPIO_EnableOutputPin(16+2, TRUE);
	// enable USB clock
	OTG_TypeDef* OTG;
	if (Controller == 0) {
		RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
		OTG = OTG_FS;
	}
	else if (Controller == 1) {
		RCC->AHB1ENR |= RCC_AHB1ENR_OTGHSEN;
		OTG = OTG_HS;
	}
	else {
		return FALSE;
	}
	//disable int
	OTG->GAHBCFG &= ~OTG_GAHBCFG_GINTMSK;

	//core init 1
	OTG->GINTSTS |= OTG_GINTSTS_RXFLVL;
	OTG->GAHBCFG |= OTG_GAHBCFG_PTXFELVL;
	//core init 2
	OTG->GUSBCFG &= ~OTG_GUSBCFG_HNPCAP;
	OTG->GUSBCFG &= ~OTG_GUSBCFG_SRPCAP;
	OTG->GUSBCFG &= ~OTG_GUSBCFG_TRDT;
	OTG->GUSBCFG |= STM32F4_USB_TRDT<<10;
	OTG->GUSBCFG |= OTG_GUSBCFG_PHYSEL;
	//core init 3
	OTG->GINTMSK |= OTG_GINTMSK_OTGINT | OTG_GINTMSK_MMISM;
	//force host mode
	OTG->GUSBCFG |= OTG_GUSBCFG_FHMOD;
	//host init
	OTG->GINTMSK |= OTG_GINTMSK_PRTIM;
	OTG->HCFG = OTG_HCFG_FSLSPCS_48MHZ;
	OTG->HPRT |= OTG_HPRT_PPWR;

	OTG->GCCFG |= (OTG_GCCFG_VBUSBSEN | OTG_GCCFG_VBUSASEN | OTG_GCCFG_NOVBUSSENS | OTG_GCCFG_PWRDWN);
	//
	//config pins and ISR
	if (Controller == 0) {
		CPU_GPIO_DisablePin(10, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)0xA2);
		CPU_GPIO_DisablePin(11, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)0xA2);
		CPU_INTC_ActivateInterrupt(OTG_FS_IRQn,         USBH_ISR, OTG);
	}
	else {
		CPU_GPIO_DisablePin(16+14, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)0xC2);
		CPU_GPIO_DisablePin(16+15, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)0xC2);
		CPU_INTC_ActivateInterrupt(OTG_HS_IRQn,         USBH_ISR, OTG);
	}

	for (int i = 0; i < 3; i++)
	{
		CPU_GPIO_SetPinState(18, 1);
		HAL_Time_Sleep_MicroSeconds(200*1000);
		CPU_GPIO_SetPinState(18, 0);
		HAL_Time_Sleep_MicroSeconds(200*1000);
	}

	//enable interrupt
	OTG->GINTSTS = 0xFFFFFFFF;
	OTG->GAHBCFG |= OTG_GAHBCFG_GINTMSK;
	return TRUE;
}
예제 #24
0
BOOL AT91_GPIO_Driver::Initialize()
{
    int i;

    // initialize the interrupt information
    {
        PIN_ISR_DESCRIPTOR* pinIsr = g_AT91_GPIO_Driver.m_PinIsr;

        for(i = 0; i < c_MaxPins; i++)
        {
            pinIsr->m_pin     = i;
            pinIsr->m_intEdge = GPIO_INT_NONE;
            pinIsr->m_isr     = STUB_GPIOISRVector;
            pinIsr->m_param   = NULL;
            pinIsr->m_flags   = 0;

            pinIsr->m_completion.Initialize( );
            pinIsr->m_completion.InitializeForISR( &PIN_ISR_DESCRIPTOR::Fire, pinIsr );

            pinIsr++;
        }
    }

    SetDebounce( 20 );


    for(i = 0; i < c_MaxPorts; i++)
    {
        // initialize pins as free
        AT91_PIO &pioX = AT91::PIO(i);

        g_AT91_GPIO_Driver.m_PinReservationInfo[i] = 0;
        
        pioX.PIO_IDR = 0xffffffff;                // Disable all interrupts
        pioX.PIO_ISR ^= 0xffffffff;
    }

    // set unsed pins as specified in platform selector
#if defined(AT91_UNUSED_GPIOS)
    {
        struct UnusedGPIO
        {
            UINT8 Pin;
            UINT8 State;
        };

        static const UnusedGPIO c_Unused[] = { AT91_UNUSED_GPIOS };

        const UnusedGPIO* ptr = c_Unused;

        for(size_t i = 0; i < ARRAYSIZE(c_Unused); i++, ptr++)
        {
            if(ptr->State == RESISTOR_DISABLED)
            {
                EnableInputPin( (GPIO_PIN)ptr->Pin, FALSE, NULL, 0, GPIO_INT_NONE, RESISTOR_DISABLED );
            }
            else
            {
                EnableOutputPin( (GPIO_PIN)ptr->Pin, (BOOL)(ptr->State == RESISTOR_PULLUP) );
            }
        }
    }
#endif

    // register interrupt handler for all ports
    if(!CPU_INTC_ActivateInterrupt( AT91C_ID_PIOA, ISR, (void*)(size_t)0 )) return FALSE;
    if(!CPU_INTC_ActivateInterrupt( AT91C_ID_PIOB, ISR, (void*)(size_t)1 )) return FALSE;
#if (AT91_MAX_GPIO > 64)
    if(!CPU_INTC_ActivateInterrupt( AT91C_ID_PIOC, ISR, (void*)(size_t)2 )) return FALSE;
#endif

#if (AT91_MAX_GPIO > 96)
    if(!CPU_INTC_ActivateInterrupt( AT91C_ID_PIOD, ISR, (void*)(size_t)3 )) return FALSE;
#endif


    // TODO: will be replaced by PMC API

    AT91_PMC &pmc = AT91::PMC();
    pmc.EnablePeriphClock(AT91C_ID_PIOA);
    pmc.EnablePeriphClock(AT91C_ID_PIOB);

#if  (AT91_MAX_GPIO > 64)
    pmc.EnablePeriphClock(AT91C_ID_PIOC);
#endif

#if  (AT91_MAX_GPIO > 96)
    pmc.EnablePeriphClock(AT91C_ID_PIOD);
#endif

    return TRUE;
}
HRESULT AT91_USBHS_Driver::Initialize( int Controller )
{
    
    ASSERT(0 == Controller);

    //UINT8 logicalEndpoint;
    UINT8 endpointNum;
    //UINT8 altInterface;
    USB_CONTROLLER_STATE     &State = UsbControllerState[Controller];
    const USB_ENDPOINT_DESCRIPTOR  *ep    = NULL;
    const USB_INTERFACE_DESCRIPTOR *itfc  = NULL;

    struct AT91_UDPHS *pUdp = (struct AT91_UDPHS *) (AT91C_BASE_UDP);
    struct AT91_UDPHS_EPT *pEp = (struct AT91_UDPHS_EPT *) (AT91C_BASE_UDP + 0x100);
    ep_dir[0]=0;
    ep_dir[1]=0;
    ep_dir[2]=0;
    ep_dir[3]=0;
    ep_dir[4]=0;
    ep_dir[5]=0;
    
    num_ep_int1= 0;
    num_ep_int2= 0;

    GLOBAL_LOCK(irq);
    
    
    // Enable USB device clock
    AT91_PMC_EnableUSBClock();
    AT91_PMC_EnableUTMIBIAS();

    // Enable the interrupt for  UDP
    CPU_INTC_ActivateInterrupt( AT91C_ID_UDP, Global_ISR, NULL);

    pUdp->UDPHS_IEN |= AT91C_UDPHS_EPT_INT_0;
    pEp->UDPHS_EPTCFG |= 0x00000043; //configuration info for control ep
//    pUdp->UDP_CSR[0] |= AT91C_UDP_EPTYPE_CTRL;

    // For all endpoints in the USB Configuration list
    //logicalEndpoint = 1;
    while( USB_NextEndpoint( &State, ep, itfc) ) // && logicalEndpoint < 11 )
    {
        // Figure out which endpoint we are initializing
        endpointNum = ep->bEndpointAddress & 0x7F;
        
        // Check interface and endpoint numbers against hardware capability
        if( endpointNum >= AT91_USBHS_Driver::c_Used_Endpoints || itfc->bInterfaceNumber > 3 )
            return S_FALSE;

/*        
        EndpointInit[logicalEndpoint].bits.EPNUM      = endpointNum;
        EndpointInit[logicalEndpoint].bits.FIFONUM    = endpointNum;
        EndpointInit[logicalEndpoint].bits.DIR        = (ep->bEndpointAddress & 0x80) ? 1 : 0;
        EndpointInit[logicalEndpoint].bits.INTERFACE  = itfc->bInterfaceNumber;
        EndpointInit[logicalEndpoint].bits.TYPE       = ep->bmAttributes & 0x03;
        EndpointInit[logicalEndpoint].bits.TRXTYP     = 3;      // Always 3 for non-control endpoints
        EndpointInit[logicalEndpoint].bits.CONFIG     = 1;      // Always only 1 configuration: #1
*/
        // Set the maximum size of the endpoint hardware FIFO
        if( (ep->bmAttributes & 0x03) == USB_ENDPOINT_ATTRIBUTE_BULK )
        {
            int endpointSize = ep->wMaxPacketSize;

            // If the endpoint maximum size in the configuration list is bogus
            if( endpointSize != 8 && endpointSize != 16 && endpointSize != 32 && endpointSize != 64 && endpointSize != 128 && endpointSize != 512 && endpointSize != 1024 )
                return S_FALSE;
            // If too large an endpoint size was requested
            if( endpointSize > s_EpAttr[endpointNum].Payload )
                return S_FALSE;
//            EndpointInit[logicalEndpoint].bits.MAXPKTSIZE = endpointSize;
            State.MaxPacketSize[endpointNum] = endpointSize;
        }
        else
        {
            // If Isochronous or Interupt type endpoint, always use the maximum size
//            EndpointInit[logicalEndpoint].bits.MAXPKTSIZE = s_EpAttr[endpointNum].Payload;
            State.MaxPacketSize[endpointNum] = s_EpAttr[endpointNum].Payload;
        }

        // Since endpoint 0 is only used for control, there is never a need to allocate a buffer for it
        // In fact State.Queues[0] is always NULL - it is a cheap placeholder to make the queueIndex = endpointIndex
        QueueBuffers[endpointNum-1].Initialize();                       // Clear queue before use
        State.Queues[endpointNum] = &QueueBuffers[endpointNum-1];       // Attach queue to endpoint
        
        
        
        pEp = (struct AT91_UDPHS_EPT *) (AT91C_BASE_UDP + 0x100 + 0x20 * (endpointNum));
        // Enable an interrupt for the endpoint & set its direction
        if( (ep->bEndpointAddress & 0x80) ? 1 : 0 )        // If transmit endpoint
        {
            State.IsTxQueue[endpointNum] = TRUE;
            
            switch(ep->bmAttributes & 0x03)
            {
                case 1:
                    pEp->UDPHS_EPTCFG |= AT91C_UDPHS_EPT_TYPE_ISO_EPT|AT91C_UDPHS_EPT_DIR_OUT;
                    
                    break;
                case 2:
                    pEp->UDPHS_EPTCFG |= AT91C_UDPHS_EPT_TYPE_BUL_EPT|AT91C_UDPHS_EPT_DIR_OUT;
                    
                    break;
                case 3:
                    pEp->UDPHS_EPTCFG |= AT91C_UDPHS_EPT_TYPE_INT_EPT|AT91C_UDPHS_EPT_DIR_OUT;
                    
                    break;
            }
            
        }
        else        // Receive endpoint
        {
            State.IsTxQueue[endpointNum] = FALSE;
            switch(ep->bmAttributes & 0x03)
            {
                case 1:
                    pEp->UDPHS_EPTCFG |= AT91C_UDPHS_EPT_TYPE_ISO_EPT|AT91C_UDPHS_EPT_DIR_IN;
                    
                    break;
                case 2:
                    pEp->UDPHS_EPTCFG |= AT91C_UDPHS_EPT_TYPE_BUL_EPT|AT91C_UDPHS_EPT_DIR_IN;
                    
                    break;
                case 3:
                    pEp->UDPHS_EPTCFG |= AT91C_UDPHS_EPT_TYPE_INT_EPT|AT91C_UDPHS_EPT_DIR_IN;
                    
                    break;
            }
        }
        
                
        pUdp->UDPHS_IEN |= (AT91C_UDPHS_EPT_INT_0 << endpointNum);

        // Move onto the next logical endpoint
        //logicalEndpoint++;
    }

    g_AT91_USBHS_Driver.pUsbControllerState  = &State;
    g_AT91_USBHS_Driver.PinsProtected = TRUE;

    State.EndpointStatus = &g_AT91_USBHS_Driver.EndpointStatus[0];
    State.EndpointCount  = c_Used_Endpoints;
    State.PacketSize     = s_EpAttr[0].Payload;

    State.FirstGetDescriptor = TRUE;
    //State.DeviceState = USB_DEVICE_STATE_DETACHED;

    ProtectPins( Controller, FALSE );
//    debug_printf("ep_dir[1]: %x, ep_dir[2]: %x, %d, %d\r\n", ep_dir[1], ep_dir[2], State.MaxPacketSize[1], State.MaxPacketSize[2]);
    

    return S_OK;
}
void EthernetWakeUp()
{
    CPU_INTC_ActivateInterrupt(ETH_IRQn, (HAL_CALLBACK_FPN)STM32F4_ETH_LWIP_interrupt, &g_STM32F4_ETH_NetIF);
    InitContinuations(&g_STM32F4_ETH_NetIF);
}
예제 #27
0
// ---------------------------------------------------------------------------
HRESULT CPU_USB_Initialize(int core)
{
    if (core >= MAX_USB_CORE || USB_ENABLED(core)) return S_FALSE;

    USB_CONTROLLER_STATE *State = CPU_USB_GetState(core);
    const USB_ENDPOINT_DESCRIPTOR  *pEpDesc;
    const USB_INTERFACE_DESCRIPTOR *pIfDesc;
    int epNum, ret;
    UINT32 queueId = 0;

    GLOBAL_LOCK(irq);

    // Initialize physical layer
    if (!USB_ENABLED(1 - core))  // No other USB controllers enabled?
    {
        LPC_CGU->PLL[CGU_USB_PLL].PLL_CTRL &= ~1; // Enable USB PLL
        while (!(LPC_CGU->PLL[CGU_USB_PLL].PLL_STAT & 1)); // Wait for USB PLL to lock
    }
    LPC_CGU->BASE_CLK[USB_CLK[core]] &= ~1;  // Enable USBx base clock
    LPC_CREG->CREG0 &= ~(1 << 5); // Enable USB0 PHY
    if (core == 1) // Special init for USB1
    {
        // Enable USB1_DP and USB1_DN on chip FS phy
        LPC_SCU->SFSUSB = 0x12; // USB device mode (0x16 for host mode)
        LPC_USB1->PORTSC1_D |= (1 << 24);
    }

    // Set USB state
    USB_STATE(core) = State;
    USB_FLAGS(core) = 0;
    ep_out_count[core] = 0;
    ep_in_count[core] = 0;

    State->EndpointStatus = USB_EPSTATUS(core);
    State->EndpointCount = USB_MAX_EP_NUM;
    State->PacketSize = MAX_EP0_SIZE;

    // Initialize USB stack
    ret = USB_InitStack(core);
    if (ret != RET_OK) return S_FALSE; // Exit if not succesful

    // Set defaults for unused endpoints
    for (epNum = 1; epNum < State->EndpointCount; epNum++)
    {
        State->IsTxQueue[epNum] = FALSE;
        State->MaxPacketSize[epNum] = MAX_EP_SIZE;
    }

    // Get endpoint configuration
    while (USB_NextEndpoint(State, pEpDesc, pIfDesc))
    {
        // Figure out which endpoint we are initializing
        epNum = pEpDesc->bEndpointAddress & 0x7F;

        // Check interface and endpoint numbers against hardware capability
        if (epNum >= State->EndpointCount || pIfDesc->bInterfaceNumber > 3)
            return S_FALSE;

        if (pEpDesc->bEndpointAddress & 0x80) State->IsTxQueue[epNum] = TRUE;

        // Set the maximum size of the endpoint hardware FIFO
        int endpointSize = pEpDesc->wMaxPacketSize;
        // Exit if the endpoint maximum size in the configuration list is bogus
        // or greater than USB_MAX_DATA_PACKET_SIZE (default=64)
        if ((endpointSize != 8 && endpointSize != 16 && endpointSize != 32 && endpointSize != 64
                && endpointSize != 128 && endpointSize != 256 && endpointSize != 512)
				|| endpointSize > USB_MAX_DATA_PACKET_SIZE)
            return S_FALSE;
        State->MaxPacketSize[epNum] = endpointSize;

        // Assign queues
        QueueBuffers[queueId].Initialize();           // Clear queue before use
        State->Queues[epNum] = &QueueBuffers[queueId];  // Attach queue to endpoint
        queueId++;

        // Isochronous endpoints are currently not supported
        if ((pEpDesc->bmAttributes & 3) == USB_ENDPOINT_ATTRIBUTE_ISOCHRONOUS) return FALSE;
    }

    // Configure CDC driver
    ret = CDC_Init(core);
    if (ret != RET_OK) return S_FALSE; // Exit if not succesful

    // Connect and enable interrupts
    CPU_USB_ProtectPins(core, FALSE);
    CPU_INTC_ActivateInterrupt(USB_IRQ[core], USB_ISR[core], 0);
    USB_ENABLED(core) = TRUE;
    State->DeviceState = USB_DEVICE_STATE_CONFIGURED; // Config done by ROM stack
    USB_StateCallback(State);

    return S_OK;
}
예제 #28
0
BOOL SD_BS_Driver::ChipInitialize(void *context)
{
    SD_BLOCK_CONFIG *config = (SD_BLOCK_CONFIG*)context;

    if(!config || !config->BlockDeviceInformation)
    {
        return FALSE;
    }

    BlockDeviceInfo *pDevInfo = config->BlockDeviceInformation;

	UINT32 alternate = 0x1C2;

	CPU_GPIO_DisablePin(PC8_SD_D0, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate);
	CPU_GPIO_DisablePin(PC9_SD_D1, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate);
	CPU_GPIO_DisablePin(PC10_SD_D2, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate);
	CPU_GPIO_DisablePin(PC11_SD_D3, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate);
	CPU_GPIO_DisablePin(PC12_SD_CLK, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)alternate);
	CPU_GPIO_DisablePin(PD2_SD_CMD, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate);

	CPU_GPIO_ReservePin( PC8_SD_D0, TRUE );
	CPU_GPIO_ReservePin( PC9_SD_D1, TRUE );
	CPU_GPIO_ReservePin( PC10_SD_D2, TRUE );
	CPU_GPIO_ReservePin( PC11_SD_D3, TRUE );
	CPU_GPIO_ReservePin( PC12_SD_CLK, TRUE );
	CPU_GPIO_ReservePin( PD2_SD_CMD, TRUE );

	RCC->APB2ENR |= (1 << 11);
	CPU_INTC_ActivateInterrupt( /*UINT32 Irq_Index*/SDIO_IRQn, /*HAL_CALLBACK_FPN ISR*/SDIO_IRQHandler, /*void* ISR_Param*/0 );

	__IO SD_Error errorstatus = SD_OK;
	//errorstatus = SD_PowerON();
	errorstatus = SD_Init();

	CPU_INTC_InterruptEnable( /*UINT32 Irq_Index*/SDIO_IRQn );

	memset(pBuffer, 0xFF, 512);
	errorstatus = SD_ReadBlock(pBuffer, 0, 512);
	//errorstatus = SD_WaitReadOperation();
	//while(SD_GetStatus() != SD_TRANSFER_OK);
   if (SD_GetStatus() != SD_TRANSFER_OK)
   {
      if (SD_GetStatus_WithTimeOut(SD_INITIALIZE_TIMEOUT)== FALSE) 
        return FALSE;
   }


	//CPU_FlushCaches();

//	// Variables to setup SD Card Dynamically.
//	//BYTE regCSD[16];   <-- Not used because we have better register access.

    BYTE C_SIZE_MULT = 0;

    BYTE TAAC, NSAC, MAX_RAN_SPEED, READ_BL_LEN, SECTOR_SIZE;

    BOOL ERASE_BL_EN;

    UINT32 C_SIZE;

    UINT64 MemCapacity = 0; //total memory size, in unit of byte

    TAAC			= SDCardInfo.SD_csd.TAAC; // regCSD[1]; /* STM // Original */
    NSAC			= SDCardInfo.SD_csd.NSAC; // regCSD[2]; /* STM // Original */
	MAX_RAN_SPEED	= SDCardInfo.SD_csd.MaxBusClkFrec; // regCSD[3]; /* STM // Original */
    READ_BL_LEN		= SDCardInfo.SD_csd.RdBlockLen; // regCSD[5] &0x0F; /* STM // Original */

	// Checks to see if the SD card is Version 1.0: Standard or Version 2.0: High Capacity
	if(SDCardInfo.SD_csd.CSDStruct == 0x00)  /*if(regCSD[0] == 0x00)*/
	// SD Version1.0
	{
		C_SIZE = SDCardInfo.SD_csd.DeviceSize; // ((regCSD[6] &0x3) << 10) | (regCSD[7] << 2) | ((regCSD[8] &0xC0) >> 6); /* STM // Original */

		C_SIZE_MULT = SDCardInfo.SD_csd.DeviceSizeMul; // ((regCSD[9] &0x03) << 1) | ((regCSD[10] &0x80) >> 7); /* STM // Original */

		ERASE_BL_EN = (SDCardInfo.SD_csd.EraseGrSize == 0x00) ? FALSE : TRUE; // ((regCSD[10] &0x40) == 0x00) ? FALSE : TRUE; /* STM // Original */

		SECTOR_SIZE = SDCardInfo.SD_csd.EraseGrMul; // ((regCSD[10] &0x3F) << 1) | ((regCSD[11] &0x80) >> 7); /* STM // Original */

		MemCapacity = SDCardInfo.CardCapacity; // (C_SIZE + 1) * (0x1 << (C_SIZE_MULT + 2)) * (0x1 << READ_BL_LEN); /* STM // Original */

		IsSDCardHC = FALSE;
	}
	else
	// SD Version2.0
	{
		C_SIZE = SDCardInfo.SD_csd.DeviceSize; // ((regCSD[7] &0x3F) << 16) | (regCSD[8] << 8) | regCSD[9]; /* STM // Original */

		ERASE_BL_EN = (SDCardInfo.SD_csd.EraseGrSize == 0x00) ? FALSE : TRUE; // ((regCSD[10] &0x40) == 0x00) ? FALSE : TRUE; /* STM // Original */

		SECTOR_SIZE = SDCardInfo.SD_csd.EraseGrMul; // ((regCSD[10] &0x3F) << 1) | ((regCSD[11] &0x80) >> 7); /* STM // Original */

		MemCapacity = SDCardInfo.CardCapacity; // (C_SIZE + 1) * 512 * 1024; /* STM // Original */

		IsSDCardHC = TRUE;
	}
    //Update SD config according to CSD register
    UINT32 SectorsPerBlock    = (ERASE_BL_EN == TRUE) ? 1 : (SECTOR_SIZE + 1);
    pDevInfo->BytesPerSector  = 512; // data bytes per sector is always 512
	pDevInfo->Size            = (ByteAddress)MemCapacity;

    BlockRegionInfo* pRegions = (BlockRegionInfo*)&pDevInfo->Regions[0];
    pRegions[0].BytesPerBlock = SectorsPerBlock * pDevInfo->BytesPerSector;
    pRegions[0].NumBlocks     = (UINT32)(MemCapacity / pRegions[0].BytesPerBlock);
        
    BlockRange* pRanges   = (BlockRange*)&pRegions[0].BlockRanges[0];

    pRanges[0].StartBlock = 0;
    pRanges[0].EndBlock   = pRegions[0].NumBlocks-1;

    return TRUE;
}
예제 #29
0
BOOL PXA271_TIMER_Driver::Initialize  ( UINT32 Timer, BOOL FreeRunning, UINT32 ClkSource, UINT32 externalSync, HAL_CALLBACK_FPN ISR, void* ISR_Param )
{
    ASSERT(Timer < c_MaxTimers);

    GLOBAL_LOCK(irq);

    if(g_PXA271_TIMER_Driver.m_descriptors[Timer].configured == TRUE) return FALSE;

    //--//

    PXA271_CLOCK_MANAGER &CLOCK = PXA271::CLKMNGR();

    CLOCK.CKEN |= PXA271_CLOCK_MANAGER::CKEN__OS_TIMER;     // Make sure the clock to the OS timer is enabled

    DisableCompareInterrupt( Timer );

    g_PXA271_TIMER_Driver.m_descriptors[Timer].isr = ISR;
    g_PXA271_TIMER_Driver.m_descriptors[Timer].arg = ISR_Param;
    
    if(ISR)
    {
        if( Timer < c_FirstPXA271_Timer )     // If one of the PXA250 compatible timers
        {
            // There are separate interrupts for each of the PXA250 compatible timers
            UINT32 interrupt = 0;

            switch(Timer)
            {
            case 0:
                interrupt = PXA271_AITC::c_IRQ_INDEX_OS_TIMER0;
                break;
            case 1:
                interrupt = PXA271_AITC::c_IRQ_INDEX_OS_TIMER1;
                break;
            case 2:
                interrupt = PXA271_AITC::c_IRQ_INDEX_OS_TIMER2;
                break;
            case 3:
                interrupt = PXA271_AITC::c_IRQ_INDEX_OS_TIMER3;
                break;
            }
 
            if( !CPU_INTC_ActivateInterrupt(interrupt, ISR, ISR_Param) ) return FALSE;
        }
        else
        {
            int i;

            // All PXA271 timers share a single interrupt
            for( i = c_FirstPXA271_Timer; (i < c_MaxTimers) && !g_PXA271_TIMER_Driver.m_descriptors[i].configured; i++ );     // Search for configured timers
            if( i == c_MaxTimers )       // If the single interrupt for all PXA271 timers has not been activated yet
            {
                if( !CPU_INTC_ActivateInterrupt(PXA271_AITC::c_IRQ_INDEX_OS_TIMER, &ISR4_11, NULL) ) return FALSE;
            }
        }
    }

    if( Timer >= c_FirstPXA271_Timer )     // If the timer is a PXA271 timer and configurable
    {
        PXA271_TIMER& TIMER = PXA271::TIMER();

        if( FreeRunning )
        {
            TIMER.OMCR[Timer-c_FirstPXA271_Timer] = PXA271_TIMER::OMCR__MATCHx | PXA271_TIMER::OMCR__PER | ClkSource | externalSync;
            TIMER.OSCR[Timer-c_FirstPXA271_Timer] = 0;        // Start counter running
        }
        else
        {
            TIMER.OMCR[Timer-c_FirstPXA271_Timer] = PXA271_TIMER::OMCR__MATCHx | PXA271_TIMER::OMCR__ROM | ClkSource | externalSync;
        }
    }

    g_PXA271_TIMER_Driver.m_descriptors[Timer].configured = TRUE;

    return TRUE;
}
BOOL PXA271_USART_Driver::Initialize( int comPort, int BaudRate, int Parity, int DataBits, int StopBits, int FlowValue )
{
    BOOL fRet = TRUE;
    
    //--//

    GLOBAL_LOCK(irq);
    UINT32       dll;
    UINT32       dlh;

    g_PXA271_USART_Driver.m_RefFlags[comPort] = 0;

    if( FlowValue & USART_FLOW_HW_OUT_EN )
    {
        // Can't ask for HW flow control if there is no pin available to implement it
        if( All_USART_ports[comPort].CTS_Pin == PXA271_GPIO::c_Pin_None )
            return FALSE;
        All_USART_ports[comPort].CTS_Pin_used = TRUE;
    }
    if( FlowValue & USART_FLOW_HW_IN_EN )
    {
        // Can't ask for HW flow control if there is no pin available to implement it
        if( All_USART_ports[comPort].RTS_Pin == PXA271_GPIO::c_Pin_None )
            return FALSE;
        All_USART_ports[comPort].RTS_Pin_used = TRUE;
    }

    ProtectPins( comPort, FALSE );      // Connect pins to the com port and connect its clock

    PXA271_USART& USART = PXA271::USART( comPort );

    const BaudRateLookup* ptr = c_BaudRateLookup;

    while(true)
    {
        if(ptr->BaudRate == BaudRate)
        {
            dll     = ptr->DLL;
            dlh     = ptr->DLH;
            break;
        }

        if(ptr->BaudRate == 0)
        {
            // TODO TODO TODO if there is not preset baud rate, calculate the parameter here
            return FALSE;
        }

        ptr++;
    }

    //--//

    // NOTE:
    // The baud rate should NOT be set while the clock to the UART is enabled.  If so, the baud rate may
    // not be accepted.  The register will read back as if it were, but the actual baud rate will be incorrect.
    USART.LCR |= PXA271_USART::LCR__DLAB;               // Enable the divisor latch registers
    USART.DLL = dll;
    USART.DLH = dlh;                                    // Set up the selected baud rate
    USART.LCR &= ~PXA271_USART::LCR__DLAB;              // Exchange divisor latch control for FIFO access

    // Set up 8 bits of data and 1 stop bit
    // LCR__STB_2 is 2 stop bits except for when data bits are 5 then it is 1 1/2 stop bits.
    switch(StopBits)
    {
        case USART_STOP_BITS_ONE:
            // do nothing (default)
            break;

        case USART_STOP_BITS_TWO:
        case USART_STOP_BITS_ONEPOINTFIVE: // based on data bits, this will either be 2 or 1.5 stop bits
            USART.LCR |= PXA271_USART::LCR__STB_2;
            break;

        // not supported
        case USART_STOP_BITS_NONE:
        default:
            fRet = FALSE;
            break;
    }

    // DataBits falls in the range of 5 to 8
    if(5 <= DataBits && DataBits <= 8)
    {
        USART.LCR |= (DataBits - 5);
    }
    else
    {
        fRet = FALSE; // invalid Data Bit Value
        USART.LCR |= PXA271_USART::LCR__WLS_8;
    }
    
    switch(Parity)
    {
        case USART_PARITY_MARK:
            USART.LCR |= PXA271_USART::LCR__STKYP;
            //fall through
        case USART_PARITY_ODD:
            // odd parity is 0
            USART.LCR |= PXA271_USART::LCR__PEN;
            break;
            
        case USART_PARITY_SPACE:
            USART.LCR |= PXA271_USART::LCR__STKYP;
            // fall through 
        case USART_PARITY_EVEN:
            USART.LCR |= PXA271_USART::LCR__EPS | PXA271_USART::LCR__PEN;
            break;

        case USART_PARITY_NONE:
            USART.LCR &= ~PXA271_USART::LCR__PEN;
            break;
            
        default:
            fRet = FALSE;
            break;
    }

    // now enable ISRs and interrupts for the com port
    CPU_INTC_ActivateInterrupt( USART_TX_IRQ_INDEX(comPort), USART_ISR, (void*)(size_t)comPort );     // Only one ISR for send and receive

    USART.MCR = PXA271_USART::MCR__OUT2;    // Connect interrupts to the AITC
    if( FlowValue & USART_FLOW_HW_OUT_EN )
        USART.MCR |= PXA271_USART::MCR__AFE;
    if( FlowValue & USART_FLOW_HW_IN_EN )
        USART.MCR |= PXA271_USART::MCR__RTS;    // Note: it may be illegal to have HW input flow control only (without HW output flow control) - untested - !!
    USART.IER = PXA271_USART::IER__UUE | PXA271_USART::IER__TIE | PXA271_USART::IER__RAVIE;        // Enable transmit & receive interrupts
    USART.FCR = PXA271_USART::FCR__ITL_1 | PXA271_USART::FCR__BUS_8 | PXA271_USART::FCR__TIL_EMPTY
        | PXA271_USART::FCR__TRFIFOE | PXA271_USART::FCR__RESETRF | PXA271_USART::FCR__RESETTF;       // Enable FIFOs, and interrupts on empty Tx FIFO and 1 char in Rx FIFO & clear FIFOs

    PXA271::CLKMNGR().CKEN |= All_USART_ports[comPort].ClockIndex;         // Enable clock to USART

    return fRet;
}