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); }
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); }
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); }
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); }