Пример #1
0
int can_send(can_id_t id, uint8_t data[], uint8_t dlc, CSP_BASE_TYPE * task_woken) {

	int i, m = -1;

	/* Disable CAN interrupt while looping MOBs */
	CAN_CLEAR_INTERRUPT();

	/* Disable interrupts while looping mailboxes */
	if (task_woken == NULL) {
		portENTER_CRITICAL();
	}

	/* Search free MOB from 0 -> CAN_TX_MOBs */
	for(i = 0; i < CAN_TX_MOBS; i++) {
		if (mbox[i] == MBOX_FREE && !(CANEN2 & (1 << i))) {
			mbox[i] = MBOX_USED;
			m = i;
			break;
		}
	}
	
	/* Enable interrupts */
	if (task_woken == NULL) {
		portEXIT_CRITICAL();
	}

	/* Enable CAN interrupt */
	CAN_SET_INTERRUPT();

	/* Return if no available MOB was found */
	if (m < 0) {
		csp_log_warn("TX overflow, no available MOB\r\n");
		return -1;
	}

	/* Select and clear mob */
	CAN_SET_MOB(m);
	CAN_MOB_ABORT();
	CAN_CLEAR_STATUS_MOB();

	/* Set identifier */
	CAN_SET_EXT_ID(id);

	/* Set data - CANMSG is auto incrementing */
	for (i = 0; i < dlc; i++)
		CANMSG = data[i];

	/* Set DLC */
	CAN_CLEAR_DLC();
	CAN_SET_DLC(dlc);

	/* Start TX */
	CAN_CONFIG_TX();

	return 0;

}
static void post_cmd(can_cmd_t * cmd) {
    uint8_t mob_handle;
    uint8_t i;

    if(cmd == NULL) return;

    mob_handle = can_get_mob_free();

    // add command to wait queue if there are no free mobs
    if(mob_handle == NO_MOB) {
        cmd->status = MOB_NOT_COMPLETED;
        list_add(can_cmd_list, cmd);
    }
    // add command to table of pending command otherwise
    else {
        can_mob[mob_handle] = cmd;
        cmd->status = MOB_PENDING;
        CAN_SET_MOB(mob_handle);
        CAN_CLEAR_MOB();

        switch(cmd->type) {
            case TX:
                if(cmd->frame->inf.ide) {
                    CAN_SET_EXT_ID(cmd->frame->inf.id);
                } else {
                    CAN_SET_STD_ID(cmd->frame->inf.id);
                }

                for(i = 0; i < cmd->frame->data.len; ++i) {
                    CANMSG = cmd->frame->data.itself[i];
                }

                if(cmd->frame->inf.rtr) {
                    CAN_SET_RTR();
                } else {
                    CAN_CLEAR_RTR();
                }
                CAN_SET_DLC(cmd->frame->data.len);
                CAN_CONFIG_TX();
                break;

            case RX:
                if (cmd->frame->inf.ide) {
                    CAN_SET_EXT_ID(can_masked_id);
                    CAN_SET_IDEMSK();
                    CAN_SET_EXT_MSK(can_mask);
                } else {
                    CAN_SET_STD_ID(can_masked_id);
                    CAN_CLEAR_IDEMSK();
                    CAN_SET_STD_MSK(can_mask);
                }
                CAN_SET_DLC(cmd->frame->data.len);
                CAN_CLEAR_RTRMSK();
                CAN_CONFIG_RX();
                break;

            default:
                cmd->status = STATUS_CLEARED;
                break;
        }
    }
}