コード例 #1
0
static void hl_print_boot_info(void)
{
    /* Print boot info regardless of the printf options (if it prints float or not) */
    #if SYS_CFG_REDUCED_PRINTF
        const unsigned int cpuClock = sys_get_cpu_clock();
        const unsigned int sig = cpuClock / (1000 * 1000);
        const unsigned int fraction = (cpuClock - (sig*1000*1000)) / 1000;
        printf("System Boot @ %u.%u Mhz\n", sig, fraction);
    #else
        printf("System Boot @ %.3f Mhz\n", sys_get_cpu_clock() / (1000 * 1000.0f));
    #endif

    if(boot_watchdog_recover == sys_get_boot_type()) {
        char taskName[sizeof(FAULT_LAST_RUNNING_TASK_NAME) * 2] = { 0 };
        memcpy(&taskName[0], (void*) &(FAULT_LAST_RUNNING_TASK_NAME), sizeof(FAULT_LAST_RUNNING_TASK_NAME));

        hl_print_line();
        printf("System rebooted after crash.  Relevant info:\n"
               "PC: 0x%08X.  LR: 0x%08X.  PSR: 0x%08X\n"
               "Possible last running OS Task: '%s'\n",
                (unsigned int)FAULT_PC, (unsigned int)FAULT_LR, (unsigned int)FAULT_PSR,
                taskName);
        hl_print_line();
        delay_ms(SYS_CFG_CRASH_STARTUP_DELAY_MS);
    }
}
コード例 #2
0
ファイル: lpc_rit.c プロジェクト: kammce/SJSU-DEV-Linux
void rit_enable(void_func_t function, uint32_t time_ms)
{
    if (0 == function) {
        return;
    }
    // Divide by zero guard
    if(0 == time_ms) {
        time_ms = 1;
    }

    // Power up first otherwise writing to RIT will give us Hard Fault
    lpc_pconp(pconp_rit, true);

    // Enable CLK/1 to simplify RICOMPVAL calculation below
    lpc_pclk(pclk_rit, clkdiv_1);

    LPC_RIT->RICTRL = 0;
    LPC_RIT->RICOUNTER = 0;
    LPC_RIT->RIMASK = 0;
    LPC_RIT->RICOMPVAL = sys_get_cpu_clock() / (1000 / time_ms);

    // Clear timer upon match, and enable timer
    const uint32_t isr_clear_bitmask = (1 << 0);
    const uint32_t timer_clear_bitmask = (1 << 1);
    const uint32_t timer_enable_bitmask = (1 << 3);
    LPC_RIT->RICTRL = isr_clear_bitmask | timer_clear_bitmask | timer_enable_bitmask;

    // Enable System Interrupt and connect the callback
    g_rit_callback = function;
    vTraceSetISRProperties(RIT_IRQn, "RIT", IP_RIT);
    NVIC_EnableIRQ(RIT_IRQn);
}
コード例 #3
0
ファイル: gps.cpp プロジェクト: ankit4970/project_wifitrack
/**************************************************************************************************
 * @brief		Initialize UART module for SIM808
 * @param[in]	UARTx	UART peripheral selected, should be:
 *  					- LPC_UART0: UART0 peripheral
 * 						- LPC_UART1: UART1 peripheral
 * 						- LPC_UART2: UART2 peripheral
 * 						- LPC_UART3: UART3 peripheral
 * 				baudrate Baudrate for UART
 * @return 		true if successful
**************************************************************************************************/
bool sim808_gps::sim808_gpsInit(LPC_UART_TypeDef *UARTx, uint32_t baudrate)
{
	uint16_t baud = 0;
	const unsigned int pclk = sys_get_cpu_clock();

	gUartSemaphore = xSemaphoreCreateBinary();

	// Turn on UART2 module
	LPC_SC->PCONP |= (1 << 24);

	// Select clock for UART2 PCLK = CCLK
	LPC_SC->PCLKSEL1 &= ~(2<<16);
	LPC_SC->PCLKSEL1 |= (1<<16);


	// Configure UART2 :8-bit character length1 :1 stop bit :Parity Disabled
	UARTx->LCR = 0x03;

	// Enable DLAB (DLAB = 1)
	UARTx->LCR |= (1<<7);

	// For baudrate 115200
	//div = 48000000/16*baudRate;// = 312;
	//divWord = 48000000/(16*115200);
	baud = (pclk / (16 * baudrate));

	UARTx->DLL = (baud & 0xFF);
	UARTx->DLM = (baud >> 8);

	// Disabling DLAB (DLAB =0)
	UARTx->LCR &= ~(1<<7) ;

	// Enable & Reset FIFOs and set 4 char timeout for Rx
	UARTx->FCR = 0x07;
	UARTx->FCR |= (3<<6);
	//UARTx->FCR &= ~(1<<3);

	// Pin select for P2.8 TXD2 and P2.9 RXD2
	LPC_PINCON->PINSEL4 &= ~((1<<16) | (1<<18));
	LPC_PINCON->PINSEL4 |= ((1<<17) | (1<<19));

	// Pin select for P4.28 TXD3 and P4.29 RXD3
	//LPC_PINCON->PINSEL9 |= ((1<<24) | (1<<25) | (1<<26) | (1<<27));
	NVIC_EnableIRQ(UART2_IRQn);
	UARTx->IER = (1 << 0) | (1 << 2); // B0:Rx, B1: Tx
	sim808_reset(LPC_GPIO0, GPS_RESET_PIN);
	printf("Starting communication\n");

	mUARTx = UARTx;
	return true;

}
コード例 #4
0
ファイル: uart3.cpp プロジェクト: amin901/cmpe
bool Uart3::init(unsigned int baudRate, int rxQSize, int txQSize)
{
    // Configure PINSEL for UART3.
    // UART3 RX/TX is at P4.28 and P4.29
    LPC_PINCON->PINSEL9 &= ~(0xF << 24); // Clear values
    LPC_PINCON->PINSEL9 |=  (0xF << 24); // Set values for UART3 Rx/Tx

    // Set UART3 Peripheral Clock divider to 1
    lpc_pclk(pclk_uart3, clkdiv_1);
    const unsigned int pclk = sys_get_cpu_clock();

    return UartDev::init(pclk, baudRate, rxQSize, txQSize);
}
コード例 #5
0
        void set_baud_rate(uint16_t req_baudrate)
        {
        	//Setting the Baud Rate 9600: Baud Rate = PCLK/16(DLM:DLL) = 48000000/16(9600)
        	uint16_t baudrate_div;

        	baudrate_div = sys_get_cpu_clock()/(16*req_baudrate); //baudrate_div = 48000000/(16*req_baudrate);

        	LPC_UART3->LCR = 128;       				 //Setting DLAB 1
        	LPC_UART3->DLL = (baudrate_div & 0xFF);		 //Setting DLL
        	LPC_UART3->DLM = (baudrate_div >> 8);		 //Setting DLM
        	//Disabling DLAB to enable THR and RBR registers and setting word length to be 8 character
        	LPC_UART3->LCR = 3;
        }
コード例 #6
0
ファイル: uart2.cpp プロジェクト: amin901/cmpe
bool Uart2::init(unsigned int baudRate, int rxQSize, int txQSize)
{
    // Configure PINSEL for UART2.
    // UART2 RX/TX is at P0.10 and P0.11 or P2.8 and P2.9
    // SJ One Board uses P2.8 and P2.9
    LPC_PINCON->PINSEL4 &= ~(0xF << 16); // Clear values
    LPC_PINCON->PINSEL4 |=  (0xA << 16); // Set values for UART2 Rx/Tx

    // Set UART2 Peripheral Clock divider to 1
    lpc_pclk(pclk_uart2, clkdiv_1);
    const unsigned int pclk = sys_get_cpu_clock();

    return UartDev::init(pclk, baudRate, rxQSize, txQSize);
}
コード例 #7
0
ファイル: uart0_min.c プロジェクト: Danielnkf/SJSU-DEV-Linux
void uart0_init(unsigned int baud_rate)
{
    const uint16_t divider = (sys_get_cpu_clock() / (16 * baud_rate) + 0.5);

	LPC_SC->PCONP |= (1 << 3);          // Enable power to UART0
	LPC_SC->PCLKSEL0 &= ~(3 << 6);
	LPC_SC->PCLKSEL0 |=  (1 << 6);      // Uart clock = CPU / 1

	LPC_PINCON->PINSEL0 &= ~(0xF << 4); // Clear values
	LPC_PINCON->PINSEL0 |= (0x5 << 4);  // Set values for UART0 Rx/Tx

	LPC_UART0->LCR = (1 << 7);	// Enable DLAB
	LPC_UART0->DLM = (divider >> 8);
	LPC_UART0->DLL = (divider >> 0);
	LPC_UART0->LCR = 3;			// 8-bit data
}
コード例 #8
0
/**
 * Initializes the minimal system including CPU Clock, UART, and Flash accelerator
 * Be careful of the order of operations!!!
 */
void low_level_init(void)
{
    rtc_init();
    m_rtc_boot_time = rtc_gettime();

    /**
     * Configure System Clock based on desired clock rate @ sys_config.h
     * Setup default interrupt priorities that will work with FreeRTOS
     */
    sys_clock_configure();
    configure_flash_acceleration(sys_get_cpu_clock());
    configure_interrupt_priorities();
    __enable_irq();

    // Setup UART with minimum I/O functions
    uart0_init(UART0_DEFAULT_RATE_BPS);
    sys_set_outchar_func(uart0_putchar);
    sys_set_inchar_func(uart0_getchar);

    /**
     *  If buffers are set to 0, so printf/scanf will behave correctly!
     *  If not set, then printf/scanf will have weird buffering/flushing effects
     */
    setvbuf(stdout, 0, _IONBF, 0);
    setvbuf(stdin,  0, _IONBF, 0);

    /**
     * Set the semaphore for the malloc lock.
     * Initialize newlib fopen() fread() calls support
     */
    syscalls_init();

    /**
     * Enable watchdog to allow us to recover in case of:
     *  - We attempt to run an application and it's not there
     *  - Application we ran crashes
     */
    sys_watchdog_enable();
    print_boot_info();
}
コード例 #9
0
/**
 * Initializes the minimal system including CPU Clock, UART, and Flash accelerator
 * Be careful of the order of the operations!!!
 */
void low_level_init(void)
{
    rtc_init();
    g_rtc_boot_time = rtc_gettime();

    /* Configure System Clock based on desired clock rate @ sys_config.h */
    sys_clock_configure();
    configure_flash_acceleration(sys_get_cpu_clock());

    /* Setup default interrupt priorities that will work with FreeRTOS */
    configure_interrupt_priorities();

    /* These methods shouldn't be needed but doing it anyway to be safe */
    NVIC_SetPriorityGrouping(0);
    __set_BASEPRI(0);
    __enable_fault_irq();
    __enable_irq();

    /* Setup UART with minimal I/O functions */
    uart0_init(SYS_CFG_UART0_BPS);
    sys_set_outchar_func(uart0_putchar);
    sys_set_inchar_func(uart0_getchar);

    /**
     * Turn off I/O buffering otherwise sometimes printf/scanf doesn't behave
     * correctly due to strange buffering and/or flushing effects.
     */
    setvbuf(stdout, 0, _IONBF, 0);
    setvbuf(stdin,  0, _IONBF, 0);

    /* Initialize newlib fopen() fread() calls support */
    syscalls_init();

    /* Enable the watchdog to allow us to recover in an event of system crash */
    sys_watchdog_enable();

    /* Uart and printf() are initialized, so print our boot-up message */
    print_boot_info();
}
コード例 #10
0
/**************************************************************************************************
 * @brief		Initialize UART peripheral for SIM808
 * @param[in]	UARTx	UART peripheral selected
 *  					- LPC_UART0: UART0 peripheral
 * 						- LPC_UART1: UART1 peripheral
 * 						- LPC_UART2: UART2 peripheral
 * 						- LPC_UART3: UART3 peripheral
 * @return 		true if success
**************************************************************************************************/
bool esp8266_wifi::esp8266_init(LPC_UART_TypeDef *UARTx, uint32_t baudrate)
{
	uint16_t baud = 0;
	const unsigned int pclk = sys_get_cpu_clock();
	// Turn on UART3 module
	LPC_SC->PCONP |= (1 << 25);

	// Select clock for UART3 PCLK = CCLK
	LPC_SC->PCLKSEL1 &= ~(2<<18);
	LPC_SC->PCLKSEL1 |= (1<<18);

	// Configure UART3 :8-bit character length1 :1 stop bit :Parity Disabled
	UARTx->LCR = 0x03;

	// Enable DLAB (DLAB = 1)
	UARTx->LCR |= (1<<7);

	// For baudrate 115200
	//div = 48000000/16*baudRate;// = 312;
	//divWord = 48000000/(16*115200);
	baud = (pclk / (16 * baudrate));

	UARTx->DLL = (baud & 0xFF);
	UARTx->DLM = (baud >> 8);

	// Disabling DLAB (DLAB =0)
	UARTx->LCR &= ~(1<<7) ;

	// Enable & Reset FIFOs and set 4 char timeout for Rx
	UARTx->FCR = 0x07;
	UARTx->FCR &= ~(1<<3);

	// Pin select for P4.28 TXD3 and P4.29 RXD3
	LPC_PINCON->PINSEL9 |= ((1<<24) | (1<<25) | (1<<26) | (1<<27));

	mUARTx = UARTx;
    return true;
}
コード例 #11
0
/**
 * Initializes the minimal system including CPU Clock, UART, and Flash accelerator
 * Be careful of the order of operations!!!
 */
void low_level_init(void)
{
    rtc_init();
    g_rtc_boot_time = rtc_gettime();

    /**
     * Configure System Clock based on desired clock rate @ sys_config.h
     * Setup default interrupt priorities that will work with FreeRTOS
     */
    sys_clock_configure();
    configure_flash_acceleration(sys_get_cpu_clock());
    configure_interrupt_priorities();
    __enable_irq();

    // Setup UART with minimum I/O functions
    uart0_init(UART0_DEFAULT_RATE_BPS);
    sys_set_outchar_func(uart0_putchar);
    sys_set_inchar_func(uart0_getchar);

    /**
     * Turn off I/O buffering otherwise sometimes printf/scanf doesn't behave
     * correctly due to strange buffering and/or flushing effects.
     */
    setvbuf(stdout, 0, _IONBF, 0);
    setvbuf(stdin,  0, _IONBF, 0);

    // Initialize newlib fopen() fread() calls support
    syscalls_init();

    /**
     * Enable watchdog to allow us to recover in case of:
     *  - We attempt to run an application and it's not there
     *  - Application we ran crashes
     */
    sys_watchdog_enable();
    print_boot_info();
}
コード例 #12
0
ファイル: iofunc.cpp プロジェクト: liveusr/selfdriving
void GLCD:: GLCD_init(void)
{
    unsigned int clock;
    clock = sys_get_cpu_clock();
    //printf("Clock freq:%d", clock);
    LPC_SC->PCONP |= power_on_uart2;
        LPC_SC->PCLKSEL1 &= ~(3 << 16);
        LPC_SC->PCLKSEL1 |= (1 << 16);
        LPC_PINCON->PINSEL4 &= ~(0xF << 16);
        LPC_PINCON->PINSEL4 |= (0xA << 16);
        LPC_UART2->LCR = enb_DLAB;
        LPC_UART2->DLM = 1; //1;
        LPC_UART2->DLL = (clock) / (16 * 9600); //56;//(clock) /(16*9600);  // baud = clock / (16*(256*DLM+DLL) )
        //LPC_UART2->DLM = 0; //1;
        //LPC_UART2->DLL = (clock) / (16 * 115200); //56;//(clock) /(16*9600);  // baud = clock / (16*(256*DLM+DLL) )

        LPC_UART2->LCR = 3;
        LPC_UART2->FCR = ((1 << 0) | (1 << 6)); // enable fifo mode

        LPC_UART2->IER = 1; //enable RDA interrupt
        NVIC_EnableIRQ(UART2_IRQn); //NOTE: singleton class in uart2.cpp is commented.

        rit_enable(timer,500);  // Run RIT for 500ms
}
コード例 #13
0
/**
 * Initializes the High Level System such as IO Pins and Drivers
 */
void high_level_init(void)
{
    // Initialize all board pins (early) that are connected internally.
    board_io_pins_initialize();
    
    #if ENABLE_TELEMETRY
        /* Add default telemetry components */
        tlm_component_add("disk");
        tlm_component_add("debug");
    #endif

    /**
     * Set-up Timer0 so that delay_ms(us) functions will work.
     * This function is used by FreeRTOS run time statistics.
     * If FreeRTOS is used, timer will be set-up anyway.
     * If FreeRTOS is not used, call it here such that delay_ms(us) functions will work.
     */
    vConfigureTimerForRunTimeStats();

    /**
     * Intentional delay here because this gives the user some time to
     * close COM Port at Hyperload and Open it at Hercules
     */
    delay_ms(STARTUP_DELAY_MS);
    hl_print_line();

    /* Print boot info */
#if USE_REDUCED_PRINTF
    const unsigned int cpuClock = sys_get_cpu_clock();
    const unsigned int sig = cpuClock / (1000 * 1000);
    const unsigned int fraction = (cpuClock - (sig*1000*1000)) / 1000;
    printf("System Boot @ %u.%u Mhz\n", sig, fraction);
#else
    printf("System Boot @ %.3f Mhz\n", sys_get_cpu_clock() / (1000 * 1000.0f));
#endif

    if(boot_watchdog_recover == sys_get_boot_type()) {
        char taskName[sizeof(FAULT_LAST_RUNNING_TASK_NAME) * 2] = { 0 };
        memcpy(&taskName[0], (void*) &(FAULT_LAST_RUNNING_TASK_NAME), sizeof(FAULT_LAST_RUNNING_TASK_NAME));

        hl_print_line();
        printf("System rebooted after crash.  Relevant info:\n"
               "PC: 0x%08X.  LR: 0x%08X.  PSR: 0x%08X\n"
               "Possible last running OS Task: '%s'\n",
                (unsigned int)FAULT_PC, (unsigned int)FAULT_LR, (unsigned int)FAULT_PSR,
                taskName);
        hl_print_line();
    }

    /**
     * Initialize the Peripherals used in the system
     * I2C2 : Used by LED Display, Acceleration Sensor, Temperature Sensor
     * ADC0 : Used by Light Sensor
     * SPI0 : Used by Nordic
     * SPI1 : Used by SD Card & External SPI Flash Memory
     */
    adc0_init();
    ssp1_init();
    ssp0_init(SPI0_CLOCK_SPEED_MHZ);
    if (!I2C2::getInstance().init(I2C2_CLOCK_SPEED_KHZ)) {
        puts("ERROR: Possible short on SDA or SCL wire (I2C2)!");
    }

    /* Initialize nordic wireless mesh network before setting up sys_setup_rit()
     * callback since it may access NULL function pointers.
     */
    if (!wireless_init()) {
        puts("ERROR: Failed to initialize wireless");
    }

    /* Set-up our RIT callback to perform some background book-keeping
     * If FreeRTOS is running, this service is disabled and FreeRTOS
     * tick hook will call hl_periodic_service()
     * @warning RIT interrupt should be setup before SD card is mounted
     *           since it relies on our timer.
     */
    sys_rit_setup(hl_periodic_service, g_time_per_rit_isr_ms);

    /**
     * If Flash is not mounted, it is probably a new board and the flash is not
     * formatted so format it, alert the user, and try to re-mount it
     */
    if(!hl_mount_storage(Storage::getFlashDrive(), " Flash "))
    {
        printf("FLASH not formatted, formatting now ... ");
        printf("%s\n", FR_OK == Storage::getFlashDrive().format() ? "Done" : "Error");
        hl_mount_storage(Storage::getFlashDrive(), " Flash ");
    }

    hl_mount_storage(Storage::getSDDrive(), "SD Card");

	/* After SD card is initted, set desired speed for spi1 */
    ssp1_set_max_clock(SPI1_CLOCK_SPEED_MHZ);
    hl_print_line();

    #if LOG_BOOT_INFO_TO_FILE
    log_boot_info(__DATE__);
    #endif

    /* Initialize all sensors of this board. */
    if(!hl_init_board_io()) {
        hl_print_line();
        LD.setLeftDigit('-');
        LD.setRightDigit('-');
        LE.setAll(0xFF);
    }
    else {
        LD.setNumber(TS.getFarenheit());
    }

    /* After Flash memory is mounted, try to set node address from a file */
    hl_wireless_set_addr_from_file();
    srand(LS.getRawValue() + time(NULL));

    // Display CPU speed in Mhz on LED display
    // LD.setNumber(sys_get_cpu_clock()/(1000*1000));

    /* Print memory information before we call main() */
    do {
        char buff[512] = { 0 };
        sys_get_mem_info_str(buff);
        printf("%s", buff);
        hl_print_line();
    } while(0);

    hl_handle_board_id();
    hl_show_prog_info();
    hl_print_line();

    puts("Calling your main()");
    hl_print_line();
}
コード例 #14
0
ファイル: can.c プロジェクト: kammce/SJSU-DEV-Linux
bool CAN_init(can_t can, uint32_t baudrate_kbps, uint16_t rxq_size, uint16_t txq_size,
              can_void_func_t bus_off_cb, can_void_func_t data_ovr_cb)
{
    if (!CAN_VALID(can)){
        return false;
    }

    can_struct_t *pStruct = CAN_STRUCT_PTR(can);
    LPC_CAN_TypeDef *pCAN = pStruct->pCanRegs;
    bool failed = true;

    /* Enable CAN Power, and select the PINS
     * CAN1 is at P0.0, P0.1 and P0.21, P0.22
     * CAN2 is at P0.4, P0.5 and P2.7,  P2.8
     * On SJ-One board, we have P0.0, P0.1, and P2.7, P2.8
     */
    if (can1 == can) {
        LPC_SC->PCONP |= can1_pconp_mask;
        LPC_PINCON->PINSEL0 &= ~(0xF << 0);
        LPC_PINCON->PINSEL0 |=  (0x5 << 0);
    }
    else if (can2 == can){
        LPC_SC->PCONP |= can2_pconp_mask;
        LPC_PINCON->PINSEL4 &= ~(0xF << 14);
        LPC_PINCON->PINSEL4 |=  (0x5 << 14);
    }

    /* Create the queues with minimum size of 1 to avoid NULL pointer reference */
    if (!pStruct->rxQ) {
        pStruct->rxQ = xQueueCreate(rxq_size ? rxq_size : 1, sizeof(can_msg_t));
    }
    if (!pStruct->txQ) {
        pStruct->txQ = xQueueCreate(txq_size ? txq_size : 1, sizeof(can_msg_t));
    }

    /* The CAN dividers must all be the same for both CANs
     * Set the dividers of CAN1, CAN2, ACF to CLK / 1
     */
    lpc_pclk(pclk_can1, clkdiv_1);
    lpc_pclk(pclk_can2, clkdiv_1);
    lpc_pclk(pclk_can_flt, clkdiv_1);

    pCAN->MOD = can_mod_reset;
    pCAN->IER = 0x0; // Disable All CAN Interrupts
    pCAN->GSR = 0x0; // Clear error counters
    pCAN->CMR = 0xE; // Abort Tx, release Rx, clear data over-run

    /**
     * About the AFMR register :
     *                      B0              B1
     * Filter Mode |    AccOff bit  |   AccBP bit   |   CAN Rx interrupt
     * Off Mode             1               0           No messages accepted
     * Bypass Mode          X               1           All messages accepted
     * FullCAN              0               0           HW acceptance filtering
     */
    LPC_CANAF->AFMR = afmr_disabled;

    // Clear pending interrupts and the CAN Filter RAM
    LPC_CANAF_RAM->mask[0] = pCAN->ICR;
    memset((void*)&(LPC_CANAF_RAM->mask[0]), 0, sizeof(LPC_CANAF_RAM->mask));

    /* Zero out the filtering registers */
    LPC_CANAF->SFF_sa     = 0;
    LPC_CANAF->SFF_GRP_sa = 0;
    LPC_CANAF->EFF_sa     = 0;
    LPC_CANAF->EFF_GRP_sa = 0;
    LPC_CANAF->ENDofTable = 0;

    /* Do not accept any messages until CAN filtering is enabled */
    LPC_CANAF->AFMR = afmr_disabled;

    /* Set the baud-rate. You can verify the settings by visiting:
     * http://www.kvaser.com/en/support/bit-timing-calculator.html
     */
    do {
        const uint32_t baudDiv = sys_get_cpu_clock() / (1000 * baudrate_kbps);
        const uint32_t SJW = 3;
        const uint32_t SAM = 0;
        uint32_t BRP = 0, TSEG1 = 0, TSEG2 = 0, NT = 0;

        /* Calculate suitable nominal time value
         * NT (nominal time) = (TSEG1 + TSEG2 + 3)
         * NT <= 24
         * TSEG1 >= 2*TSEG2
         */
        failed = true;
        for(NT=24; NT > 0; NT-=2) {
            if ((baudDiv % NT)==0) {
                BRP = baudDiv / NT - 1;
                NT--;
                TSEG2 = (NT/3) - 1;
                TSEG1 = NT -(NT/3) - 1;
                failed = false;
                break;
            }
        }

        if (!failed) {
            pCAN->BTR  = (SAM << 23) | (TSEG2<<20) | (TSEG1<<16) | (SJW<<14) | BRP;
            // CANx->BTR = 0x002B001D; // 48Mhz 100Khz
        }
    } while (0);

    /* If everything okay so far, enable the CAN interrupts */
    if (!failed) {
        /* At minimum, we need Rx/Tx interrupts */
        pCAN->IER = (intr_rx | intr_all_tx);

        /* Enable BUS-off interrupt and callback if given */
        if (bus_off_cb) {
            pStruct->bus_error = bus_off_cb;
            pCAN->IER |= g_can_bus_err_intr;
        }
        /* Enable data-overrun interrupt and callback if given */
        if (data_ovr_cb) {
            pStruct->data_overrun = data_ovr_cb;
            pCAN->IER |= intr_ovrn;
        }

        /* Finally, enable the actual CPU core interrupt */
        vTraceSetISRProperties(CAN_IRQn, "CAN", IP_can);
        NVIC_EnableIRQ(CAN_IRQn);
    }

    /* return true if all is well */
    return (false == failed);
}