int can_frequency(can_t *obj, int f) { int pclk = PeripheralClock; int btr = can_speed(pclk, (unsigned int)f, 1); if (btr > 0) { uint32_t modmask = can_disable(obj); obj->dev->BTR = btr; obj->dev->MOD = modmask; return 1; } else { return 0; } }
/** * @brief Configures the desired CAN device with the desired frequency. * * @param obj The can device to configure. * @param f The desired frequency. * * @return RTEMS_SUCCESSFUL if could be set, RTEMS_INVALID_NUMBER otherwise. */ static rtems_status_code can_frequency( const can_driver_entry *const obj, const can_freq freq ) { rtems_status_code sc = RTEMS_INVALID_NUMBER; const uint32_t btr = can_speed( LPC176X_CCLK, LPC176X_PCLKDIV, freq, 1 ); if ( btr != WRONG_BTR_VALUE ) { sc = RTEMS_SUCCESSFUL; uint32_t modmask = can_disable( obj ); obj->device->BTR = btr; obj->device->MOD = modmask; } /*else couldnt found a good timing for the desired frequency, return RTEMS_INVALID_NUMBER.*/ return sc; }
int can_frequency(can_t *obj, int f) { int pclk = HAL_RCC_GetPCLK1Freq(); int btr = can_speed(pclk, (unsigned int)f, 1); CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); if (btr > 0) { can->MCR |= CAN_MCR_INRQ ; while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { } can->BTR = btr; can->MCR &= ~(uint32_t)CAN_MCR_INRQ; while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { } return 1; } else { return 0; } }
int can_frequency(can_t *obj, int f) { int pclk = HAL_RCC_GetPCLK1Freq(); int btr = can_speed(pclk, (unsigned int)f, 1); CAN_TypeDef *can = obj->CanHandle.Instance; uint32_t tickstart = 0; int status = 1; if (btr > 0) { can->MCR |= CAN_MCR_INRQ ; /* Get tick */ tickstart = HAL_GetTick(); while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { if ((HAL_GetTick() - tickstart) > 2) { status = 0; break; } } if (status != 0) { /* Do not erase all BTR registers (e.g. silent mode), only the * ones calculated in can_speed */ can->BTR &= ~(CAN_BTR_TS2 | CAN_BTR_TS1 | CAN_BTR_SJW | CAN_BTR_BRP); can->BTR |= btr; can->MCR &= ~(uint32_t)CAN_MCR_INRQ; /* Get tick */ tickstart = HAL_GetTick(); while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { if ((HAL_GetTick() - tickstart) > 2) { status = 0; break; } } if (status == 0) { error("can ESR 0x%04x.%04x + timeout status %d", (can->ESR & 0xFFFF0000) >> 16, (can->ESR & 0xFFFF), status); }
int main() { uint8_t do_lpm, is_ext; int i, j, k; uint32_t msgid; WDTCTL = WDTPW | WDTHOLD; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; BCSCTL3 = LFXT1S_2; while (BCSCTL3 & LFXT1OF) ; P1SEL &= ~BIT0; P1SEL2 &= ~BIT0; P1DIR |= BIT0; P1OUT &= ~BIT0; sleep_counter = SLEEP_COUNTER; inbuf[8] = '\0'; can_init(); if (can_speed(500000, 1, 3) < 0) { P1OUT |= BIT0; LPM4; } // LCD init P2SEL &= ~(BIT0 | BIT5); P2SEL2 &= ~(BIT0 | BIT5); P2DIR |= BIT0 | BIT5; P2OUT |= BIT0 | BIT5; msp1202_init(); msp1202_puts("CAN printer\n0x00000080-\n"); can_rx_setmask(0, 0xFFFFFFFF, 1); can_rx_setmask(1, 0xFFFFFFFF, 1); can_rx_setfilter(0, 0, 0x00000080); can_rx_mode(0, MCP2515_RXB0CTRL_MODE_RECV_STD_OR_EXT); can_ioctl(MCP2515_OPTION_LOOPBACK, 0); can_ioctl(MCP2515_OPTION_ONESHOT, 0); can_ioctl(MCP2515_OPTION_ROLLOVER, 1); /* Flowchart for program flow: * * START * | * +---------<-------------------+-----------<-----------------------+ * | | | * \|/ /|\ | * -------------- | | * / \ +------+ | | * < Is IRQ pending? > No->---| LPM4 |->--+ | * \ / +------+ /|\ * ------------- | * Yes | * | | * \_/ | * ----------- ------------- | * / \ / \ | * < Is IRQ_ERROR? > Yes->--< Is IRQ_HANDLED? > Yes->-------------------------+ * \ / \ / | * ----------- ------------- | * No No | * | | /|\ * \_/ \_/ | * -------- -------- +-----------------+ | * / \ / \ | Cancel TX using | | * < Is IRQ_RX? > No->---->---< Is IRQ_TX? > Yes->--| can_tx_cancel() |->----+ * \ / \ / +-----------------+ | * -------- -------- | * Yes No | * | | /|\ * \_/ \_/ | * +----------------+ +-------------------+ | * | Pull data | | Bus error, wait | | * | using can_recv | | 100ms and recheck |->---------------------------+ * +----------------+ | IRQ. | | * | +-------------------+ | * \_/ | * +--------------+ /|\ * | Write buffer | | * | contents to | | * | LCD using |->--------------------------->---------------------------+ * | msp1202_puts | * +--------------+ * * * */ while(1) { do_lpm = 1; if (mcp2515_irq) { irq = can_irq_handler(); if (irq & MCP2515_IRQ_ERROR) { if ( !(irq & MCP2515_IRQ_HANDLED) ) { if (irq & MCP2515_IRQ_TX) { can_tx_cancel(); } else { // Bus error; wait 100ms, recheck P1OUT |= BIT0; __delay_cycles(1600000); P1OUT &= ~BIT0; do_lpm = 0; } } else { // RX overflow, most likely msp1202_puts("RX OVERFLOW\n"); } } if (irq & MCP2515_IRQ_RX) { j = 0; k = can_rx_pending(); do { i = can_recv(&msgid, &is_ext, inbuf+j); if ( !(i & 0x40) ) { j += i; } //msp1202_putc(k + '0', 0); msp1202_putc(' ', 0); } while ( (k = can_rx_pending()) >= 0 ); //inbuf[j++] = '\n'; inbuf[j] = '\0'; inbuf[j] = '\0'; msp1202_puts((char*)inbuf); //msp1202_putc('\n', 1); } else { if (irq & MCP2515_IRQ_TX) { can_tx_cancel(); } } } if ( do_lpm && !(mcp2515_irq & MCP2515_IRQ_FLAGGED) ) { LPM4; } } return 0; }