rtems_status_code can_write( const lpc176x_can_number minor, const can_message *const message ) { const can_driver_entry *const can_driver = &can_driver_table[ minor ]; can_device *const obj = can_driver->device; const uint32_t CANStatus = obj->SR; const registers_can_message *const msg = &( message->registers ); rtems_status_code sc = RTEMS_IO_ERROR; can_transmit_number transmit_buffer; can_enable( can_driver ); for ( transmit_buffer = CAN_TRANSMIT1; ( sc != RTEMS_SUCCESSFUL ) && ( transmit_buffer < CAN_NUMBER_OF_TRANSMIT_BUFFERS ); ++transmit_buffer ) { if ( CANStatus & transmit_info[ transmit_buffer ].can_status_mask ) { sc = RTEMS_SUCCESSFUL; obj->transmit[ transmit_buffer ] = *msg; obj->CMR = transmit_info[ transmit_buffer ].not_cc_cmr_value; } /*else can buffer busy, try with the next.*/ } return sc; }
static void can_drivers_setup() { // Configure the CAN PB12/13 gpio_set_can_rx(GPIO_B, GPIO_PIN_12); gpio_set_can_tx(GPIO_B, GPIO_PIN_13); // Start it can_enable(CAN_2, 1000000); }
void can_monitor(can_t *obj, int silent) { uint32_t mod_mask = can_disable(obj); if (silent) { obj->dev->MOD |= (1 << 1); } else { obj->dev->MOD &= ~(1 << 1); } if (!(mod_mask & 1)) { can_enable(obj); } }
int can_write(can_t *obj, CAN_Message msg, int cc) { unsigned int CANStatus; CANMsg m; can_enable(obj); m.id = msg.id ; m.dlc = msg.len & 0xF; m.rtr = msg.type; m.type = msg.format; memcpy(m.data, msg.data, msg.len); const unsigned int *buf = (const unsigned int *)&m; CANStatus = obj->dev->SR; if (CANStatus & 0x00000004) { obj->dev->TFI1 = buf[0] & 0xC00F0000; obj->dev->TID1 = buf[1]; obj->dev->TDA1 = buf[2]; obj->dev->TDB1 = buf[3]; if(cc) { obj->dev->CMR = 0x30; } else { obj->dev->CMR = 0x21; } return 1; } else if (CANStatus & 0x00000400) { obj->dev->TFI2 = buf[0] & 0xC00F0000; obj->dev->TID2 = buf[1]; obj->dev->TDA2 = buf[2]; obj->dev->TDB2 = buf[3]; if (cc) { obj->dev->CMR = 0x50; } else { obj->dev->CMR = 0x41; } return 1; } else if (CANStatus & 0x00040000) { obj->dev->TFI3 = buf[0] & 0xC00F0000; obj->dev->TID3 = buf[1]; obj->dev->TDA3 = buf[2]; obj->dev->TDB3 = buf[3]; if (cc) { obj->dev->CMR = 0x90; } else { obj->dev->CMR = 0x81; } return 1; } return 0; }
/** * @brief Enables the interrupt type passed to the desired CAN device. * * @param number The CAN device to enable the interrupts. * @param type The type of interrupt to enable. */ static inline void can_enable_interrupt( const lpc176x_can_number number, const can_irq_type type ) { const can_driver_entry *const driver = &can_driver_table[ number ]; const uint32_t ier = 1 << type; can_disable( driver ); driver->device->IER |= ier; can_enable( driver ); }
rtems_status_code can_read( const lpc176x_can_number minor, can_message *message ) { rtems_status_code sc = RTEMS_IO_ERROR; const can_driver_entry *const can_driver = &can_driver_table[ minor ]; can_device *const dev = can_driver->device; registers_can_message *const msg = &( message->registers ); can_enable( can_driver ); if ( dev->GSR & CAN_GSR_RBS_MASK ) { sc = RTEMS_SUCCESSFUL; *msg = dev->receive; dev->CMR = CAN_CMR_RRB_MASK; /* release receive buffer. */ } /* else Message not received.*/ return sc; }
int can_mode(can_t *obj, CanMode mode) { int success = 0; switch (mode) { case MODE_RESET: LPC_C_CAN0->CANCNTL &=~CANCNTL_TEST; can_disable(obj); success = 1; break; case MODE_NORMAL: LPC_C_CAN0->CANCNTL &=~CANCNTL_TEST; can_enable(obj); success = 1; break; case MODE_SILENT: LPC_C_CAN0->CANCNTL |= CANCNTL_TEST; LPC_C_CAN0->CANTEST |= CANTEST_SILENT; LPC_C_CAN0->CANTEST &=~ CANTEST_LBACK; success = 1; break; case MODE_TEST_LOCAL: LPC_C_CAN0->CANCNTL |= CANCNTL_TEST; LPC_C_CAN0->CANTEST &=~CANTEST_SILENT; LPC_C_CAN0->CANTEST |= CANTEST_LBACK; success = 1; break; case MODE_TEST_SILENT: LPC_C_CAN0->CANCNTL |= CANCNTL_TEST; LPC_C_CAN0->CANTEST |= (CANTEST_LBACK | CANTEST_SILENT); success = 1; break; case MODE_TEST_GLOBAL: default: success = 0; break; } return success; }
int can_read(can_t *obj, CAN_Message *msg, int handle) { CANMsg x; unsigned int *i = (unsigned int *)&x; can_enable(obj); if (obj->dev->GSR & 0x1) { *i++ = obj->dev->RFS; // Frame *i++ = obj->dev->RID; // ID *i++ = obj->dev->RDA; // Data A *i++ = obj->dev->RDB; // Data B obj->dev->CMR = 0x04; // release receive buffer msg->id = x.id; msg->len = x.dlc; msg->format = (x.type)? CANExtended : CANStandard; msg->type = (x.rtr)? CANRemote: CANData; memcpy(msg->data,x.data,x.dlc); return 1; } return 0; }