void can_init_mobs(void) { /* INITIALIZE MOB0 */ // Data reception mailbox. message.pt_data = &data0[0]; // point message object to first element of data buffer message.ctrl.ide = 0; // standard CAN frame type (2.0A) message.id.std = id_array[0]; // populate ID field with ID Tag message.cmd = CMD_RX_DATA; // assign this as a receiving message object. message.dlc = 8; // Max length of a CAN message. mob_number = 0; while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); // wait for MOb to configure /* INITIALIZE MOB1 */ // Command reception mailbox. message.pt_data = &data1[0]; message.ctrl.ide = 0; message.id.std = id_array[1]; message.cmd = CMD_RX_DATA; message.dlc = 8; mob_number = 1; while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); // wait for MOb to configure /* INITIALIZE MOB2 */ // Housekeeping request mailbox. message.pt_data = &data2[0]; message.ctrl.ide = 0; message.id.std = id_array[2]; message.cmd = CMD_RX_DATA; message.dlc = 8; mob_number = 2; while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); // wait for MOb to configure /* INITIALIZE MOB3 */ // Time-check mailbox. message.pt_data = &data3[0]; message.ctrl.ide = 0; message.id.std = id_array[3]; message.cmd = CMD_RX_DATA; message.dlc = 8; mob_number = 3; while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); // wait for MOb to configure /* INITIALIZE MOB5 */ message.pt_data = &data5[0]; // point message object to first element of data buffer message.ctrl.ide = 0; // standard CAN frame type (2.0A) message.id.std = id_array[5]; // populate ID field with ID Tag message.cmd = CMD_RX_DATA; // assign this as a producer message object (Housekeeping MOB). message.dlc = 8; // Max length of a CAN message. mob_number = 5; while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); // wait for MOB to configure return; }
void send_data_CAN(void) { // --- Init Reply data sensor_message.pt_data = &sensor_buffer[0]; while(1) { sensor_buffer[0] = (U8)(dummy_counter); sensor_buffer[1] = (U8)(dummy_counter+10); sensor_buffer[2] = (U8)(dummy_counter+20); sensor_buffer[3] = (U8)(dummy_counter+30); sensor_buffer[4] = (U8)(dummy_counter+40); sensor_buffer[5] = (U8)(dummy_counter+50); sensor_buffer[6] = (U8)(dummy_counter+60); sensor_buffer[7] = (U8)(convertanalog(1)); // --- Auto-reply Command sensor_message.ctrl.ide = 0; //- CAN 2.0A sensor_message.dlc = 8; //- Message with x-byte data sensor_message.id.std = MY_ID_TAG; sensor_message.cmd = CMD_RX; // --- Enable reply while(can_cmd(&sensor_message) != CAN_CMD_ACCEPTED); // --- Wait for Reply completed while(can_get_status(&sensor_message) == CAN_STATUS_NOT_COMPLETED); PORTA ^=_BV(PORTA7); dummy_counter++; } }
void CANAbortCMD(void){ if((can_Status==CAN_Send)||(can_Status==CAN_Pending)){ Timer0_Stop(); can_queue[can_queue_tail]->cmd=CMD_ABORT; can_cmd(can_queue[can_queue_tail]); AddError(ERROR_CAN_SEND); can_Status=CAN_Ready; can_queue_tail=(can_queue_tail+1)%CAN_QUEUE_SIZE; } }
void CANSend(void){ can_queue[can_queue_tail]->cmd=CMD_TX_DATA; if(can_cmd(can_queue[can_queue_tail])!=CAN_CMD_ACCEPTED){ can_Status=CAN_Ready; AddError(ERROR_CAN_ACCEPTED); }else{ CANGIE|=(1<<ENERR); Timer0_Start(); } }
void CANSendData(void){ if(can_queue_head!=can_queue_tail){ if(can_rx!=0){ CANGIE&=~(1<<ENRX); can_rx->cmd=CMD_ABORT; can_cmd(can_rx); while(can_get_status(can_rx)==CAN_STATUS_NOT_COMPLETED); } if(CANGIE&(1<<ENIT)){ can_Status=CAN_Send; CANSend(); }else{ can_Status=CAN_Pending; } }else if(can_rx!=0){ can_rx->cmd=CMD_RX_DATA; can_cmd(can_rx); CANGIE|=(1<<ENRX); } }
void CANSendNext(void){ Timer0_Stop(); #ifdef WDT_DELAY wdt_reset(); #endif can_queue[can_queue_tail]->cmd = CMD_ABORT; can_cmd(can_queue[can_queue_tail]); can_Status=CAN_Ready; can_queue_tail=(can_queue_tail+1)%CAN_QUEUE_SIZE; CANSendData(); }
uint8_t can_update_rx_msg(st_cmd_t* msg, uint8_t msg_id, uint8_t dlc) { uint8_t i; msg->id.std = msg_id; msg->ctrl.ide = 0; msg->ctrl.rtr = 0; msg->dlc = dlc; msg->cmd = CMD_RX_DATA_MASKED; while(can_cmd(msg) != CAN_CMD_ACCEPTED); }
/* funktion til at sende en besked der er dlc byte lang og er ikke blocking * return values: * 0 = Besked ikke kommet i udbakke * 1 = Besked kommet i udbakke */ uint8_t can_send_non_blocking(uint8_t msg_id, void* buf, uint8_t dlc) { tx_remote_msg.pt_data = buf; tx_remote_msg.id.std = msg_id; tx_remote_msg.ctrl.ide = 0; tx_remote_msg.ctrl.rtr = 1; tx_remote_msg.dlc = dlc; tx_remote_msg.cmd = CMD_TX_DATA; tx_remote_msg.blocking = 0; /* For non blocking */ /* can_cmd function extended with a feature to enable interrupt for * the message mob picked for the message */ if (can_cmd(&tx_remote_msg) != CAN_CMD_ACCEPTED){ return 0; // No free mob could not put message in mail box }else{ return 1; } }
void can_send_message(uint8_t* data_array, uint8_t id) { uint8_t i = 0; message.pt_data = &data4[0]; // point message object to first element of data buffer message.ctrl.ide = 0; // standard CAN frame type (2.0A) message.id.std = id; // populate ID field with ID Tag message.cmd = CMD_TX_DATA; // assign this as a transmitting message object. message.dlc = 8; // Max length of a CAN message. mob_number = 4; for (i = 0; i < 8; i ++) { data4[i] = *(data_array + i) ; // Message to be sent back to the OBC. } while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); // wait for MOb4 to configure while(can_get_status(&message, mob_number) == CAN_STATUS_NOT_COMPLETED); // wait for a message to send or fail. return; }
void clean_up_msg(uint8_t mailbox) { if(mailbox == 0) { message.ctrl.ide = 0; // standard CAN frame type (2.0A) message.cmd = CMD_RX_DATA; // assign this as a receiving message object. message.dlc = 8; // Max length of a CAN message. mob_number = mailbox; message.pt_data = &data0[0]; // point message object to first element of data buffer message.id.std = id_array[0]; // populate ID field with ID Tag while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); // wait for MOb to configure return; } if(mailbox == 1) { message.ctrl.ide = 0; // standard CAN frame type (2.0A) message.cmd = CMD_RX_DATA; // assign this as a receiving message object. message.dlc = 8; // Max length of a CAN message. mob_number = mailbox; message.pt_data = &data1[0]; message.id.std = SUB0_ID1; while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); return; } if(mailbox == 2) { message.ctrl.ide = 0; // standard CAN frame type (2.0A) message.cmd = CMD_RX_DATA; // assign this as a receiving message object. message.dlc = 8; // Max length of a CAN message. mob_number = mailbox; message.pt_data = &data2[0]; message.id.std = id_array[2]; while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); return; } if(mailbox == 3) { message.ctrl.ide = 0; // standard CAN frame type (2.0A) message.cmd = CMD_RX_DATA; // assign this as a receiving message object. message.dlc = 8; // Max length of a CAN message. mob_number = mailbox; message.pt_data = &data3[0]; message.id.std = id_array[3]; while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); return; } if(mailbox == 5) { message.ctrl.ide = 0; // standard CAN frame type (2.0A) message.cmd = CMD_RX_DATA; // assign this as a receiving message object. message.dlc = 8; // Max length of a CAN message. mob_number = mailbox; message.pt_data = &data5[0]; message.id.std = id_array[5]; while(can_cmd(&message, mob_number) != CAN_CMD_ACCEPTED); return; } return; }
void can_sendAliveMsg(){ can_cmd(& aliveMessage); }
void can_sendShutDownMsg(){ can_cmd(& shutDownMessage); }
void can_sendDataMsg(){ can_cmd(& dataMessage); }
//------------------------------------------------------------------------------ // @fn send_sensor_values //! //! An Identifier value (CAN2.0A) is given to DVK90CAN1 board (ex: 0x080). //! 1) The first operation is to detect a CAN receive remote frame with //! ID == MY_ID_TAG. //! 2) The second operation is to send a CAN data frame with the same ID and as //! data: //! - the temperatue value (1 byte ), //! - the luminosity value (1 byte ), //! - the VCC-IN value (2 bytes). //! 3) IAP detection. //! //! @warning - Use DVK90CAN1 board, //! - can_init() must be perform before, //! - CAN_Bootloader_IAR Ver3 needed. //! //! @param none //! //! @return none //! //------------------------------------------------------------------------------ void send_sensor_values(void) { U8 temp, expected_nnb; U8 iap_buffer[8]; U8 sensor_buffer[8]; U16 v_in; st_cmd_t iap_message; st_cmd_t sensor_message; U16 ack_jingle[] = { 100, 30, A7, 0 }; // --- Init data and command for IAP detection expected_nnb = Farflash_rd_byte(NNB_ADDRESS); iap_message.pt_data = &iap_buffer[0]; iap_message.ctrl.ide = 0; //-- CAN 2.0A iap_message.dlc = 1; //-- Message with 1-byte data = NNB iap_message.id.std = 0x7FF & (((U16)(Farflash_rd_byte(CRIS_ADDRESS)))<< 4); iap_message.cmd = CMD_RX_DATA_MASKED; // --- Init data and command for REPLY-sensor message sensor_message.pt_data = &sensor_buffer[0]; sensor_message.ctrl.ide = 0; //-- CAN 2.0A sensor_message.dlc = 4; //-- Message with 4-byte data sensor_message.id.std = MY_ID_TAG; sensor_message.cmd = CMD_REPLY_MASKED; sensor_buffer[0] = (U8)(get_temperature()); sensor_buffer[1] = get_luminosity(); v_in = get_vin(); sensor_buffer[2] = (U8)(v_in >> 8 ); sensor_buffer[3] = (U8)(v_in ); // --- Enable IAP detection while(can_cmd(&iap_message) != CAN_CMD_ACCEPTED); // --- Enable REPLY for sensor message while(can_cmd(&sensor_message) != CAN_CMD_ACCEPTED); while(1) { // --- Test REPLY completed temp = can_get_status(&sensor_message); if(temp == CAN_STATUS_COMPLETED) { // --- Re-prepare data for the reply sensor_buffer[0] = (U8)(get_temperature()); sensor_buffer[1] = get_luminosity(); v_in = get_vin(); sensor_buffer[2] = (U8)(v_in >> 8 ); sensor_buffer[3] = (U8)(v_in ); // --- Re-enable REPLY for sensor message while(can_cmd(&sensor_message) != CAN_CMD_ACCEPTED); // --- Acoustic acknowledge (must be short !) audio_play_song(ack_jingle); } // --- Test IAP detected temp = can_get_status(&iap_message); if(temp == CAN_STATUS_COMPLETED) { // --- Control of length & data if((iap_buffer[0] == expected_nnb) && (iap_message.dlc == 1)) { Indirect_jump_to(BOOT_W_ADDRESS); //-- Bye ! } else { // --- Re-enable IAP detection while(can_cmd(&iap_message) != CAN_CMD_ACCEPTED); } } } // while(
//------------------------------------------------------------------------------ // @fn can_isp_protocol_task //! //! This function manages the CAN ISP PROTOCOL. //! //! @warning none //! //! @param none //! //! @return 0: Re-evaluation of bit-timming asked //! 1: OK (for a new command) //! //------------------------------------------------------------------------------ Bool can_isp_protocol_task(void) { U8 u8_temp,i; //- Prepare Rx Command can_isp_rx_msg.dlc = 8; // Max can_isp_rx_msg.id.std = base_isp_id; //- Rx Command while (can_cmd(&can_isp_rx_msg) != CAN_CMD_ACCEPTED); //- Wait for Rx completed while (1) { u8_temp = can_get_status(&can_isp_rx_msg); if (u8_temp != CAN_STATUS_NOT_COMPLETED) break; // Out of: while(1... } if (u8_temp == CAN_STATUS_ERROR) { return(0); // Re-evaluation of bit-timming asked, out of the function } //flash BLUE to show packet received PORTG ^= _BV(PING0); //--- Switch following CAN ISP resquest received switch ((can_isp_rx_msg.id.std - base_isp_id)) { //- OPEN or CLOSE COMMUNICATION (0x00) ------------------------------------- case CAN_ID_SELECT_NODE: //- The length of the received frame needs to be tested because a //- confusion can appears in case of IAP network when a node //- acknowledges its "Open Communication". Else, this 2-byte //- response could be interpreted by a non-involved slave node //- as an "Open Communication"!!! if ( ((can_isp_rx_buffer[0]==get_conf_byte(NNB))||(can_isp_rx_buffer[0]==0xFF)) \ && (can_isp_rx_msg.dlc==1) ) { if (can_communication_opened == FALSE) { can_communication_opened = TRUE; isp_select_memory = MEM_DEFAULT; isp_select_page = PAGE_DEFAULT; } else { can_communication_opened = FALSE; isp_prog_on_going = FALSE; } //- Acknowledge frame can_isp_tx_msg.id.std = (base_isp_id + CAN_ID_SELECT_NODE); can_isp_tx_msg.dlc = 2; can_isp_tx_buffer[0] = BOOT_VERSION; can_isp_tx_buffer[1] = can_communication_opened; can_isp_send_frame(); PORTG ^= _BV(PING1); } //- Else nothing break; //- START PROGRAMMING (0x01) ------------------------------------- case CAN_ID_PROG_START: if (can_communication_opened) { //- FULL ERASE ------------------------------------------- if ( (can_isp_rx_buffer[0] == CAN_FULL_ERASE_1) && \ (can_isp_rx_buffer[1] == CAN_FULL_ERASE_2) && \ (can_isp_rx_buffer[2] == CAN_FULL_ERASE_3) ) { if (isp_memory_erase() == FALSE) { can_isp_send_error_frame(); break; //- Exit from: case ... } } //- START PROGRAMMING ------------------------------------ else if (can_isp_rx_buffer[0] == CAN_INIT_PROG) { isp_address_range ( ( (((U16)can_isp_rx_buffer[1])<<8) | ((U16)can_isp_rx_buffer[2]) ) , \ ( (((U16)can_isp_rx_buffer[3])<<8) | ((U16)can_isp_rx_buffer[4]) ) ) ; loc_buf_index = 0; isp_prog_on_going = TRUE; //- Save pointer and size for block programming using isp_start_address_copy = isp_start_address; isp_number_of_bytes_copy = isp_number_of_bytes; } //- ERROR WHEN START PROGRAMMING ------------------------- else { can_isp_send_error_frame(); break; //- Exit from: case ... } //- Acknowledge frame can_isp_tx_msg.id.std = (base_isp_id + CAN_ID_PROG_START); can_isp_tx_buffer[0] = COMMAND_OK; can_isp_tx_msg.dlc = 1; if(isp_prog_on_going == TRUE) { can_isp_tx_msg.dlc = 0; } can_isp_send_frame(); } //- Else nothing break; //- DATA PROGRAMMING (0x02) -------------------------------------- case CAN_ID_PROG_DATA: if (can_communication_opened) { if ( isp_prog_on_going == TRUE ) { //- BLOCK PROGRAMMING -------------------------------- for (i=0; i<can_isp_rx_msg.dlc; i++) { local_buffer[loc_buf_index] = can_isp_rx_buffer[i]; loc_buf_index++; u8_temp = 0x00; } if ( (loc_buf_index > ((U16)(LOCAL_BUFFER_SIZE - 0x08))) || \ (loc_buf_index == isp_number_of_bytes) ) { u8_temp = isp_prog_block(local_buffer, loc_buf_index); loc_buf_index = 0; } //- Acknowledge frame can_isp_tx_msg.id.std = (base_isp_id + CAN_ID_PROG_DATA); can_isp_tx_msg.dlc = 1; if (u8_temp == 0x00) { can_isp_tx_buffer[0] = OK_NEW_DATA; } else if (u8_temp == 0x01) { can_isp_tx_buffer[0] = OK_END_OF_DATA; isp_prog_on_going = FALSE; //- Restore pointer and size isp_start_address = isp_start_address_copy; isp_number_of_bytes = isp_number_of_bytes_copy; } else //- u8_temp == 0xFF, error (ex: SSB cause) { isp_prog_on_going = FALSE; can_isp_send_error_frame(); break; //- Exit from: case ... //- CARE: Pointer and size not restored } can_isp_send_frame(); } //- ERROR WHEN BLOCK PROGRAMMING ------------------------- else { can_isp_send_error_frame(); } } //- Else nothing break; //- DATA DISPLAY (0x03) ------------------------------------------ case CAN_ID_DISPLAY_DATA: if (can_communication_opened) { //- Prepare acknowledge frame can_isp_tx_msg.id.std = (base_isp_id + CAN_ID_DISPLAY_DATA); can_isp_tx_msg.dlc = 0; isp_address_range ( ( (((U16)can_isp_rx_buffer[1])<<8) | ((U16)can_isp_rx_buffer[2]) ) , \ ( (((U16)can_isp_rx_buffer[3])<<8) | ((U16)can_isp_rx_buffer[4]) ) ) ; //- Save pointer and size isp_start_address_copy = isp_start_address; isp_number_of_bytes_copy = isp_number_of_bytes; //- READ DATA -------------------------------------------- if (can_isp_rx_buffer[0] == CAN_READ_DATA) { can_isp_tx_msg.dlc = 8; //- default while (1) { //- Using of "can_isp_tx_buffer" to store the blocks u8_temp = isp_read_block(can_isp_tx_buffer,8); if (u8_temp == 0x00) { can_isp_send_frame(); //- Intermediate block } else if (u8_temp == 0x01) { can_isp_tx_msg.dlc = isp_number_of_bytes; can_isp_send_frame(); //- Last block break; //- Exit from: while ... } else //- u8_temp == 0xFF, error (ex: SSB cause) { can_isp_send_error_frame(); break; //- Exit from: while ... } } } //- BLANK CHECK ------------------------------------------ else if (can_isp_rx_buffer[0] == CAN_BLANK_CHECK) { if ( isp_blank_check() == FALSE ) { //- Prepare to send 1st failed address can_isp_tx_msg.dlc = 2; can_isp_tx_buffer[0] = (U8)(isp_start_address >>8); can_isp_tx_buffer[1] = (U8)(isp_start_address); } //- Acknowledge frame or send 1st failed address can_isp_send_frame(); } //- ERROR WHEN DATA DISPLAY ------------------------------ else { can_isp_send_error_frame(); break; //- Exit from: case ... } //- Restore pointer and size isp_start_address = isp_start_address_copy; isp_number_of_bytes = isp_number_of_bytes_copy; }
void CANStartRx(st_cmd_t* Rx){ can_rx=Rx; can_rx->cmd=CMD_RX_DATA; can_cmd(can_rx); }