Пример #1
0
static void _sema4_isr(pointer p)
{
    CORE_MUTEX_DEVICE_PTR   device_ptr = (CORE_MUTEX_DEVICE_PTR) p;
    uint_32                 i;
    vuchar_ptr              gate_ptr;
    uchar                   lock = _psp_core_num()+1;
    uint_16                 mask = 0x8000;
    boolean                 waiting;

    for (i=0;i<SEMA4_NUM_GATES;i++) {
        if (*device_ptr->CPNTF_PTR & mask ) {
            // An interrupt is pending on this mutex, the only way to clear it is to lock it (either
            // by this core or another)
            gate_ptr = device_ptr->MUTEX_PTR[idx[i]]->GATE_PTR;
            *gate_ptr = lock;
            if (*gate_ptr == lock) {
                // Now, check to see if any task is waiting for it
                waiting = FALSE;
                if (device_ptr->MUTEX_PTR[idx[i]]) {
                    if (_taskq_get_value(device_ptr->MUTEX_PTR[idx[i]]->WAIT_Q)) {
                        _taskq_resume(device_ptr->MUTEX_PTR[idx[i]]->WAIT_Q, FALSE);
                        waiting = TRUE;
                    }
                }
                if (!waiting) {
                    // No task was waiting, give it back - this can occur due to a failed trylock
                    *gate_ptr = SEMA4_UNLOCK;
                }
            }
        }
        mask >>= 1;
   }
}
Пример #2
0
VQINTC_REG_STRUCT_PTR _bsp_get_qintc_base_address(void)
{
    switch (_psp_core_num()) {
        case 0:  return (VQINTC_REG_STRUCT_PTR) MPXS30_INTC_BASE;
        case 1:  return (VQINTC_REG_STRUCT_PTR) MPXS30_INTC_1_BASE;
        default: return NULL;
    }
}
Пример #3
0
uint_32 _core_mutex_create_internal(CORE_MUTEX_PTR mutex_ptr, uint_32 core_num, uint_32 mutex_num, uint_32 policy, boolean allocated )
{
    CORE_MUTEX_COMPONENT_PTR component_ptr = _core_mutext_get_component_ptr();

#if MQX_CHECK_ERRORS
    if (component_ptr == NULL) {
        return MQX_COMPONENT_DOES_NOT_EXIST;
    }

    // range check mutex_id
    if (mutex_num>=SEMA4_NUM_GATES) {
        return (MQX_INVALID_PARAMETER);
    }

    if (core_num>=PSP_NUM_CORES) {
        return (MQX_INVALID_PARAMETER);
    }

    if (mutex_ptr==NULL) {
        return MQX_INVALID_PARAMETER;
    }
#endif

    mutex_ptr->VALID    = CORE_MUTEX_VALID;
    mutex_ptr->GATE_NUM = mutex_num;
    mutex_ptr->GATE_PTR = &(component_ptr->DEVICE[core_num].SEMA4_PTR->GATE[mutex_ptr->GATE_NUM]);
    mutex_ptr->WAIT_Q   = _taskq_create(policy);
#if MQX_CHECK_ERRORS
    if (mutex_ptr->WAIT_Q==NULL) {
        return MQX_TASKQ_CREATE_FAILED;
    }
#endif

    _int_disable();
#if MQX_CHECK_ERRORS
    if (component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num] !=NULL) {
        _int_enable();
        _taskq_destroy(mutex_ptr->WAIT_Q);
        return MQX_COMPONENT_EXISTS;
    }
#endif
    component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num]=mutex_ptr;

    // Need to remember if we allocated this mutex, or user did
    if (allocated) {
       component_ptr->DEVICE[core_num].ALLOCED |= (1<<mutex_num);
    }

    // Enable 'unlocked' interrupt for this core
    if (_psp_core_num()==0) {
        component_ptr->DEVICE[core_num].SEMA4_PTR->CP0INE |= 1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]);	//1 << (SEMA4_NUM_GATES-1-mutex_num);
    } else {
        component_ptr->DEVICE[core_num].SEMA4_PTR->CP1INE |= 1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]);	//1 << (SEMA4_NUM_GATES-1-mutex_num);
    }
    _int_enable();

    return COREMUTEX_OK;
}
Пример #4
0
uint_32 _core_mutex_install( const CORE_MUTEX_INIT_STRUCT *init_ptr )
{
   CORE_MUTEX_COMPONENT_PTR   component_ptr = _core_mutext_get_component_ptr();
   PSP_INTERRUPT_TABLE_INDEX  vector;
   uint_32                    i;

#if MQX_CHECK_ERRORS
   if (component_ptr!=NULL) {
      return MQX_COMPONENT_EXISTS;
   }
#endif

   component_ptr = _mem_alloc_system_zero(sizeof(*component_ptr));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (component_ptr==NULL) {
       return MQX_OUT_OF_MEMORY;
   }
#endif

   for (i=0;i<SEMA4_NUM_DEVICES;i++) {
       vector = _bsp_get_sema4_vector(i);
       component_ptr->DEVICE[i].SEMA4_PTR = _bsp_get_sema4_base_address(i);
       if (_psp_core_num()==0) {
           component_ptr->DEVICE[i].CPNTF_PTR = &(component_ptr->DEVICE[i].SEMA4_PTR->CP0NTF);
       } else {
           component_ptr->DEVICE[i].CPNTF_PTR = &(component_ptr->DEVICE[i].SEMA4_PTR->CP1NTF);
       }
#if MQX_CHECK_ERRORS
       if ((component_ptr->DEVICE[i].SEMA4_PTR == NULL) || (vector==0)) {
           _mem_free(component_ptr);
           return MQX_INVALID_DEVICE;
       }
#endif
   }

   _int_disable();
#if MQX_CHECK_ERRORS
   if (_core_mutext_get_component_ptr()) {
       _int_enable();
       _mem_free(component_ptr);
       return MQX_COMPONENT_EXISTS;
   }
#endif

   _core_mutext_set_component_ptr(component_ptr);
   _int_enable();


   for (i=0;i<SEMA4_NUM_DEVICES;i++) {
       vector = _bsp_get_sema4_vector(i);
       _int_install_isr(vector, _sema4_isr, &component_ptr->DEVICE[i]);
       _bsp_int_init(vector, init_ptr->INT_PRIORITY, 0, TRUE);
   }

   return COREMUTEX_OK;
}
Пример #5
0
VQINTC_REG_STRUCT_PTR _bsp_get_qintc_base_address(void)
{
    // Don't use CORECFG for INTC
    switch (_psp_core_num()) {
        case 0:  return (VQINTC_REG_STRUCT_PTR) MPXN20_INTC_BASE;
        /* Disabled, currently MQX for PXN does not support Core Z0 */
        /*case 1:  return (VQINTC_REG_STRUCT_PTR) MPXN20_INTC_1_BASE;*/
        default: return NULL;
    }
}
Пример #6
0
static uchar_ptr _bsp_vtopr(uchar_ptr ptr)
{
    uint_32 addr = (uint_32) ptr;

    if ( (addr >= MPXS30_SRAM_CORE_0_BASE) && (addr < MPXS30_SRAM_CORE_1_END) && (addr & BSP_VIRTIAL_MEMORY_BIT) ) {
        addr &= ~(BSP_VIRTIAL_MEMORY_BIT);
        if (_psp_core_num()==0) {
            addr += (MPXS30_SRAM_CORE_1_BASE-MPXS30_SRAM_CORE_0_BASE);
        }
     }

     return (uchar_ptr) addr;
}
Пример #7
0
uint_32 _core_mutex_unlock( CORE_MUTEX_PTR core_mutex_ptr )
{
    uchar lock = _psp_core_num()+1;
    vuchar_ptr gate_ptr;

#if MQX_CHECK_ERRORS
    if (core_mutex_ptr == NULL) {
        return MQX_INVALID_POINTER;
    }

    if (core_mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    gate_ptr = core_mutex_ptr->GATE_PTR;

    // Make sure it is locked by this core
    if ( *gate_ptr != lock) {
        return MQX_NOT_RESOURCE_OWNER;
    }

#if BSPCFG_CORE_MUTEX_STATS
    core_mutex_ptr->UNLOCKS++;
#endif

    // Unlock if
    *gate_ptr = SEMA4_UNLOCK;


    // See if this core has any other tasks waiting for this lock
    if (_taskq_get_value(core_mutex_ptr->WAIT_Q)) {

        // if so, have to queue the next request
        _sema4_int_disable();
        *gate_ptr = lock;
        if (*gate_ptr == lock) {
            // if we got it, wake up the next task
            _taskq_resume(core_mutex_ptr->WAIT_Q, FALSE);
        }
        _sema4_int_enable();
    }

    return COREMUTEX_OK;
}
Пример #8
0
/*!
 * \brief Lock the core mutex.
 * 
 * This function attempts to lock a mutex. If the mutex is already locked 
 * by another task the function blocks and waits until it is possible to lock 
 * the mutex for the calling task.
 * 
 * \param[in] core_mutex_ptr   Pointer to core_mutex structure.
 *
 * \return MQX_INVALID_POINTER (Wrong pointer to the core_mutex structure provided.)
 * \return COREMUTEX_OK (Core mutex successfully locked.)
 * 
 * \see _core_mutex_unlock 
 * \see _core_mutex_trylock 
 */ 
uint32_t _core_mutex_lock( CORE_MUTEX_PTR core_mutex_ptr )
{
    unsigned char lock = _psp_core_num()+1;

#if MQX_CHECK_ERRORS
    if (core_mutex_ptr == NULL) {
        return MQX_INVALID_POINTER;
    }

    if (core_mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    _sema4_int_disable();
#if BSPCFG_CORE_MUTEX_STATS
    core_mutex_ptr->LOCKS++;
#endif

    /* Check to see if this core already own it */
    if (*core_mutex_ptr->GATE_PTR == lock) {
        /* Yes, then we have to wait for owning task to release it */
        #if BSPCFG_CORE_MUTEX_STATS
            core_mutex_ptr->WAITS++;
        #endif
        _taskq_suspend(core_mutex_ptr->WAIT_Q);

    } else {
        /* can only try to lock the mutex if another task is not waiting  otherwise we need to get in line */
        if (_taskq_get_value(core_mutex_ptr->WAIT_Q)==0) {
            *core_mutex_ptr->GATE_PTR = lock;
        }
        if (*core_mutex_ptr->GATE_PTR != lock) {
            #if BSPCFG_CORE_MUTEX_STATS
                core_mutex_ptr->WAITS++;
            #endif
            _taskq_suspend(core_mutex_ptr->WAIT_Q);
            /* Our turn now */
        }
    }
    _sema4_int_enable();

    return COREMUTEX_OK;
}
Пример #9
0
pointer _bsp_ptov(pointer ptr)
{
    uint_32 addr = (uint_32) ptr;

    if (_psp_core_num()==0) {
        if ( ( (addr>=MPXS30_SRAM_CORE_0_BASE) && (addr<MPXS30_SRAM_CORE_0_END)) ||
             ( (addr>=MPXS30_SRAM_CORE_1_BASE) && (addr<MPXS30_SRAM_CORE_1_END)) ) {

            addr |= BSP_VIRTIAL_MEMORY_BIT;
        }
    } else {
        if ( (addr>=MPXS30_SRAM_CORE_0_BASE) && (addr<MPXS30_SRAM_CORE_0_END)) {
            addr = (addr - MPXS30_SRAM_CORE_0_BASE + MPXS30_SRAM_CORE_1_BASE) | BSP_VIRTIAL_MEMORY_BIT;
        } else if ((addr>=MPXS30_SRAM_CORE_1_BASE)&&(addr<MPXS30_SRAM_CORE_1_END)) {
            addr = (addr - MPXS30_SRAM_CORE_1_BASE + MPXS30_SRAM_CORE_0_BASE) | BSP_VIRTIAL_MEMORY_BIT;
        }
    }

    return (pointer) addr;
}
Пример #10
0
uint_32 _core_mutex_trylock( CORE_MUTEX_PTR core_mutex_ptr )
{
    vuchar_ptr  gate_ptr;
    uchar       lock = _psp_core_num()+1;
    boolean     locked = FALSE;

#if MQX_CHECK_ERRORS
    if (core_mutex_ptr == NULL) {
        return MQX_INVALID_POINTER;
    }

    if (core_mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    gate_ptr = core_mutex_ptr->GATE_PTR;

    _sema4_int_disable();
    // If any other task is pending on the semaphore, then it's already locked
    if (_taskq_get_value(core_mutex_ptr->WAIT_Q)==0) {
        // Or if it's not unlocked...
        if (*gate_ptr == SEMA4_UNLOCK) {
            *gate_ptr = lock;
            // double check to ensure another core didn't lock it before we could
            locked = (*gate_ptr == lock);
        }
    }
    _sema4_int_enable();

    if(locked) {
        return COREMUTEX_LOCKED;
    }
    else {
        return COREMUTEX_UNLOCKED;
    }
}
Пример #11
0
uint_32 _core_mutex_destroy( CORE_MUTEX_PTR mutex_ptr )
{
    CORE_MUTEX_COMPONENT_PTR    component_ptr = _core_mutext_get_component_ptr();
    SEMA4_MemMapPtr sema4_ptr;
    pointer                     tq;
    uint_32                     core_num, mutex_num,i;

#if MQX_CHECK_ERRORS
    if (component_ptr == NULL) {
       return MQX_COMPONENT_DOES_NOT_EXIST;
    }

    if (mutex_ptr==NULL) {
        return MQX_INVALID_POINTER;
    }

    if (mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    mutex_num = mutex_ptr->GATE_NUM;

    // figure out which device this mutex is associated with
    for (i=0;i<SEMA4_NUM_DEVICES;i++) {
        sema4_ptr = _bsp_get_sema4_base_address(i);
        if (&sema4_ptr->GATE[mutex_num] == mutex_ptr->GATE_PTR) {
            core_num = i;
            break;
        }
    }

    _int_disable();
#if MQX_CHECK_ERRORS
    if (component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num] == NULL) {
       _int_enable();
       return MQX_COMPONENT_DOES_NOT_EXIST;
    }
#endif

    component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num] = NULL;

    if (_psp_core_num()==0) {
        component_ptr->DEVICE[core_num].SEMA4_PTR->CP0INE &= ~(1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]));	//~(1 << (SEMA4_NUM_GATES-1-mutex_num));
    } else {
        component_ptr->DEVICE[core_num].SEMA4_PTR->CP1INE &= ~(1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]));	//~(1 << (SEMA4_NUM_GATES-1-mutex_num));
    }
    tq = mutex_ptr->WAIT_Q;
    mutex_ptr->VALID=0;
    _int_enable();

    if (component_ptr->DEVICE[core_num].ALLOCED & (1<<mutex_num)) {
        component_ptr->DEVICE[core_num].ALLOCED &=  ~(1<<mutex_num);
    } else {
        mutex_ptr=NULL;
    }
    _taskq_destroy(tq);
    if (mutex_ptr) {
        _mem_free(mutex_ptr);
    }

    return COREMUTEX_OK;
}
Пример #12
0
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _psp_core_peripheral_address
* Returned Value   : pointer to peripheral
* Comments         :
*    This function returns the supplied address if the peripheral is enabled
* on this core
*
*END*----------------------------------------------------------------------*/
pointer _psp_core_peripheral_address(uint_32 config, pointer address)
{
    return (config & (1<<_psp_core_num())) ? address : NULL;
}
Пример #13
0
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _psp_core_peripheral_enabled
* Returned Value   : pointer to peripheral
* Comments         :
*    This function returns the supplied address if the peripheral is enabled
* on this core
*
*END*----------------------------------------------------------------------*/
boolean _psp_core_peripheral_enabled(uint_32 config)
{
    return (config & (1<<_psp_core_num()));
}
Пример #14
0
void _bsp_io_pcb_shm_int_trigger(uint_32 vector)
{
    _qintc_set_core_sw_interrupt(_psp_core_num()==0?1:0,vector);
}
Пример #15
0
uint_32 _bsp_enable_card
   (
      void
   )
{
    KERNEL_DATA_STRUCT_PTR        kernel_data;
    uint_32                       result;

    /* Enable Timer */
    _e200_enable_timer(BSP_TIMEBASE_USES_EXTERNAL_CLK);

    if (_psp_core_num()==0) {
        P1_Start( __boot);
    }

    _GET_KERNEL_DATA(kernel_data);

    _mqx_set_cpu_type(MQX_CPU);

    /* Set the bsp exit handler, called by _mqx_exit */
    _mqx_set_exit_handler(_bsp_exit_handler);

    /* Initialize the MPXSxx support functions */
    _mpxsxx_initialize_support();


    /* Initialize the interrupt handling */
    result =  _psp_int_init(BSP_FIRST_INTERRUPT_VECTOR_USED, BSP_LAST_INTERRUPT_VECTOR_USED);
    if (result != MQX_OK) {
        return result;
    }

    /* Initialize peripheral bridge */
    //_qpbridge_init(pbridge_mprot_config, ELEMENTS_OF(pbridge_mprot_config));

    /* Initialize Enhanced Interrupt Controller */
    result =  _qintc_install(_bsp_get_qintc_base_address(), PSP_EXCPT_EXTERNAL);
    if (result != MQX_OK) {
        return result;
    }

    /* enable processor recognition of External/Decrementer/Fit interrupts */
    _PSP_SET_SR (_PSP_GET_SR() | PSP_MSR_EE);

#if BSPCFG_ENABLE_PIT_TIMER
    _qpit_timer_install_kernel(BSPCFG_TIMER_PIT_DEVICE, BSPCFG_TIMER_PIT_CHANNEL,BSP_ALARM_FREQUENCY, BSP_PERI1_CLOCK, BSPCFG_TIMER_INT_LEVEL);
    //_e200_decrementer_null_install();
#else
    _e200_decrementer_timer_install(BSP_ALARM_FREQUENCY, BSP_TIMEBASE_CLOCK);
#endif


    /*------------------------------------------------------------------------*/
    /*
    ** Setup MMU page tables
    */

    if (_mqx_monitor_type == MQX_MONITOR_TYPE_NONE) {
        _mmu_init(NULL);
        // First, mark the three TLBs that the boot code used as 'not-free'
        _mmu_reserve_tlb(BSP_FLASH_TLB);
        _mmu_reserve_tlb(BSP_RAM_TLB);
        _mmu_reserve_tlb(BSP_PERIPHERAL_TLB);

        // Next, add regions for RAM.
        //                        Physical Address                  Virtual Address              Size                    Attributes
        _mmu_add_virtual_region(_bsp_vtop(BSP_PRIVATE_RAM_START),  BSP_PRIVATE_RAM_START,       BSP_PRIVATE_RAM_SIZE,   BSP_PRIVATE_RAM_ATTR,        BSP_PID_MQX);
        _mmu_add_virtual_region(_bsp_vtop(BSP_SHARED_RAM_START),   BSP_SHARED_RAM_START,        BSP_SHARED_RAM_SIZE,    BSP_SHARED_RAM_ATTR,         BSP_PID_MQX);
        _mmu_add_virtual_region(_bsp_vtopr(BSP_PRIVATE_RAM_START), BSP_REMOTE_PRIVATE_RAM_START,BSP_PRIVATE_RAM_SIZE,   BSP_REMOTE_PRIVATE_RAM_ATTR, BSP_PID_MQX);
        _mmu_add_virtual_region(_bsp_vtopr(BSP_SHARED_RAM_START),  BSP_REMOTE_SHARED_RAM_START, BSP_SHARED_RAM_SIZE,    BSP_SHARED_RAM_ATTR,         BSP_PID_MQX);
        _mmu_add_virtual_region(_bsp_vtop(BSP_UNCACHED_DATA_START),BSP_UNCACHED_DATA_START,     BSP_UNCACHED_DATA_SIZE, BSP_UNCACHED_DATA_ATTR,      BSP_PID_MQX);

        // switch PID from 1 (boot) to 2 (MQX)
        _psp_set_pid(BSP_PID_MQX);

        // Reclaim the BOOT RAM TLB
        _mmu_release_tlb(BSP_RAM_TLB);

#ifndef BSP_CACHE_INHIBIT
        _icache_enable(0);
        _dcache_enable(0);
#endif
    }


#if BSPCFG_ENABLE_CPP
    /* initialize C++ constructors */
#if defined(__DCC__) || defined(__HIGHC__)
    __init();
#elif defined(__CODEWARRIOR__)
    __cpp_init();
#endif
#endif

#if BSPCFG_CORE_MUTEX
    result = _core_mutex_install(&_core_mutex_init_info);
    if (result != MQX_OK) {
        return result;
    }
#endif

    /*------------------------------------------------------------------------*/
    /*
    ** Initialize the I/O Sub-system
    */
    #if BSPCFG_ENABLE_IO_SUBSYSTEM
        /* Initialize the I/O Sub-system */
        result = _io_init();
        if (result != MQX_OK) {
            return result;
        }

     #if PSP_HAS_DEVICE_PROTECTION
     if (!_bsp_lwgpio_enable_access(0)) {
         return MQX_INVALID_DEVICE;
     }
     #endif

        /* Install device drivers */
        #if BSPCFG_ENABLE_TTYA
            if (_psp_core_peripheral_enabled(CORECFG_LINFLEX_0)) {
                _linflexd_serial_polled_install("ttya:", &_bsp_linflexd0_init);
            }
        #endif
        #if BSPCFG_ENABLE_ITTYA
            if (_psp_core_peripheral_enabled(CORECFG_LINFLEX_0)) {
                _linflexd_serial_int_install("ittya:", &_bsp_linflexd0_init);
            }
        #endif

        #if BSPCFG_ENABLE_TTYB
            if (_psp_core_peripheral_enabled(CORECFG_LINFLEX_1)) {
                _linflexd_serial_polled_install("ttyb:", &_bsp_linflexd1_init);
            }
        #endif
        #if BSPCFG_ENABLE_ITTYB
            if (_psp_core_peripheral_enabled(CORECFG_LINFLEX_1)) {
                _linflexd_serial_int_install("ittyb:", &_bsp_linflexd1_init);
            }
        #endif

        #if BSPCFG_ENABLE_TTYC
            if (_psp_core_peripheral_enabled(CORECFG_LINFLEX_2)) {
                _linflexd_serial_polled_install("ttyc:", &_bsp_linflexd2_init);
            }
        #endif
        #if BSPCFG_ENABLE_ITTYC
            if (_psp_core_peripheral_enabled(CORECFG_LINFLEX_2)) {
                _linflexd_serial_int_install("ittyc:", &_bsp_linflexd2_init);
            }
        #endif

        #if BSPCFG_ENABLE_TTYD
            if (_psp_core_peripheral_enabled(CORECFG_LINFLEX_3)) {
                _linflexd_serial_polled_install("ttyd:", &_bsp_linflexd3_init);
            }
        #endif
        #if BSPCFG_ENABLE_ITTYD
            if (_psp_core_peripheral_enabled(CORECFG_LINFLEX_3)) {
            _linflexd_serial_int_install("ittyd:", &_bsp_linflexd3_init);
            }
        #endif

        #if BSPCFG_ENABLE_SPI0
            if (_psp_core_peripheral_enabled(CORECFG_SPI_0)) {
                _io_spi_install("spi0:", &_bsp_spi0_init);
            }
        #endif

        #if BSPCFG_ENABLE_SPI1
            if (_psp_core_peripheral_enabled(CORECFG_SPI_1)) {
                _io_spi_install("spi1:", &_bsp_spi1_init);
            }
        #endif

        #if BSPCFG_ENABLE_SPI2
            if (_psp_core_peripheral_enabled(CORECFG_SPI_2)) {
                _io_spi_install("spi2:", &_bsp_spi2_init);
            }
        #endif
        
        #if BSPCFG_ENABLE_I2C0
            if (_psp_core_peripheral_enabled(CORECFG_I2C_0)) {
                _qi2c_polled_install("i2c0:", &_bsp_i2c0_init);
            }
        #endif
        #if BSPCFG_ENABLE_II2C0
            if (_psp_core_peripheral_enabled(CORECFG_I2C_0)) {
                _qi2c_int_install("ii2c0:", &_bsp_i2c0_init);
            }
        #endif
        #if BSPCFG_ENABLE_I2C1
            if (_psp_core_peripheral_enabled(CORECFG_I2C_1)) {
                _qi2c_polled_install("i2c1:", &_bsp_i2c1_init);
            }
        #endif
        #if BSPCFG_ENABLE_II2C1
            if (_psp_core_peripheral_enabled(CORECFG_I2C_1)) {
                _qi2c_int_install("ii2c1:", &_bsp_i2c1_init);
            }
        #endif
        #if BSPCFG_ENABLE_I2C2
            if (_psp_core_peripheral_enabled(CORECFG_I2C_2)) {
                _qi2c_polled_install("i2c2:", &_bsp_i2c2_init);
            }
        #endif
        #if BSPCFG_ENABLE_II2C2
            if (_psp_core_peripheral_enabled(CORECFG_I2C_2)) {
                _qi2c_int_install("ii2c2:", &_bsp_i2c2_init);
            }
        #endif

        #if BSPCFG_ENABLE_FLASHX
            _io_flashx_install("flashx:", &_bsp_data_flashx_init);
            /* code flash support in alpha stage, not tested! */
            /* _io_flashx_install("flashx_code:", &_bsp_code_flashx_init); */
        #endif

        #if BSPCFG_ENABLE_LWADC
            #if BSPCFG_ENABLE_LWADC0
            if (_psp_core_peripheral_enabled(CORECFG_ADC_0)) {
                    _lwadc_init(&lwadc0_init);
            }
            #endif
            #if BSPCFG_ENABLE_LWADC1
                if (_psp_core_peripheral_enabled(CORECFG_ADC_1)) {
                    _lwadc_init(&lwadc1_init);
                }
            #endif
            #if BSPCFG_ENABLE_LWADC2
                if (_psp_core_peripheral_enabled(CORECFG_ADC_2)) {
                    _lwadc_init(&lwadc2_init);
                }
            #endif
            #if BSPCFG_ENABLE_LWADC3
                if (_psp_core_peripheral_enabled(CORECFG_ADC_3)) {
                    _lwadc_init(&lwadc3_init);
                }
            #endif
        #endif

        #ifdef BSP_DEFAULT_IO_CHANNEL_DEFINED
            /* Initialize the default serial I/O */
            _io_serial_default_init();
        #endif
   #endif
   return MQX_OK;
}