/*---------------------------------------------------------------------- INCLUDE ----------------------------------------------------------------------*/ #include "Os.h" #include "nces_can.h" #include "rc_car.h" #define NULL ( 0 ) /* IDタイプ */ typedef uint32 TYPE_ID; typedef struct { TYPE_ID recv_id; /* 受信したID */ uint8 mask; /* マスクパターン */ uint8 enable; /* メッセージバッファ有効無効 */ uint8 len; /* メッセージデータ長 */ uint8 data[8]; /* 送受信データ */ } TYPE_RMB_INFO; typedef struct { TYPE_ID set_id; /* 設定したID */ uint8 mask; /* マスクパターン */ uint8 enable; /* メッセージバッファ有効無効 */ uint8 len; /* メッセージデータ長 */ uint8 data[8]; /* 送受信データ */ } TYPE_TMB_INFO; static TYPE_RMB_INFO g_RMB_INFO[DEF_RMB_MAX]; static TYPE_TMB_INFO g_TMB_INFO[DEF_TMB_MAX]; STATUS NcanInit(uint8 no) { uint16 j, k; for( j = 0; j < DEF_RMB_MAX; j++ ) { g_RMB_INFO[j].recv_id = 0; g_RMB_INFO[j].mask = 0; g_RMB_INFO[j].enable = 0; g_RMB_INFO[j].len = 0; for( k = 0; k < 8; k++ ) { g_RMB_INFO[j].data[k] = 0; } } for( j = 0; j < DEF_TMB_MAX; j++ ) { g_TMB_INFO[j].set_id = 0; g_TMB_INFO[j].mask = 0; g_TMB_INFO[j].enable = 0; g_TMB_INFO[j].len = 0; for( k = 0; k < 8; k++ ) { g_RMB_INFO[j].data[k] = 0; } } /* コントローラを停止状態で初期化 */ CANC_WR_MODE_REG(CANC_MODE_STOP); /* 割込み許可 */ // CANC_WR_IRQ_EN_REG(IRQ_SET_ENABLE); CANC_WR_IRQ_EN_REG(0x03); /* アクセプタンスフィルタの設定 */ /* 全体のアクセプタンスコードレジスタ(全て許可)の設定 */ CANC_WR_ACCEPTANCE_CODE_REG(0xFFFFFFFFU); /* 全体のアクセプタンスマスクレジスタ(全て許可)の設定 */ CANC_WR_ACCEPTANCE_MASK_REG(0xFFFFFFFFU); /* レジスタの初期化 */ /* 未送信のメッセージをキャンセルする */ CANC_WR_TXABORT_REG(TXABORT_CLEAR); /* エラーカウンタレジスタの値を初期化する(送信、受信ともに値が0で無い場合、受信エラーカウンタの変更は不可) */ CANC_WR_ERROR_CNT_REG(ERROR_CNT_CLEAR); /* セルフ送受信要求レジスタを送受信要求を無しにする */ CANC_WR_RXSELFREQ_REG(RXSELFREQ_CLEAR); /* 受信ウェイトレジスタをウェイト処理オフにする */ CANC_WR_RXWAIT_REG(RXWAIT_OFF); /* 送信完了レジスタを送信未完了にする */ CANC_WR_TXCMP_REG(TXCMP_CLEAR); /* 送信キャンセル完了レジスタを送信キャンセル未完了にする */ CANC_WR_TXABORTCMP_REG(TXABORTCMP_CLEAR); /* 受信完了レジスタを受信データ無しにする */ CANC_WR_RXCMP_REG(RXCMP_CLEAR); /* 受信オーバーライトレジスタを上書き未発生にする */ CANC_RD_RXOVERWRITE_REG(); /* 受信割込み許可レジスタを割り込み許可にする */ CANC_WR_IRQ_RXEN_REG(IRQ_RXEN_PERMIT); /* 割り込み要求レジスタを割り込み未発生にする */ /* readすることで、値が初期値(割込み未発生)にリセットされる */ CANC_RD_IRQ_REG(); /* ボーレートの設定 */ CANC_WR_CLKDIV_BUSTIM_REG(BAUDRATE_500); return( STATUS_OK ); } /** メールボックス設定 * @param *mb_num:MB番号 * @param *direction:送受信方向 DIR_RECV or DIR_SND * @param ide:ID種別 * @param *id:ID * @param *mask:マスク * @param remote:データ種別 * @retval STATUS_OK * @retval STATUS_ERROR */ STATUS NcanSetMailBoxInfo(uint8 no, uint8 mb_num, uint8 direction, uint8 ide, uint32 id, uint8 mask, uint32 remote){ uint32 can_id_reg; if (direction == DIR_RECV) { /* 対象を設定する */ CANC_WR_MBOXWIN_REG(mb_num); /* 各受信メッセージボックスのアクセプタンスコードレジスタの設定 */ can_id_reg = ((uint32) id) << ACCEPTANCE_OFFSET; CANC_WR_RXMBOX_ACCEPTANCE_CODE_REG(can_id_reg); /* 各受信メッセージボックスのアクセプタンスマスクレジスタの設定 */ CANC_WR_RXMBOX_ACCEPTANCE_MASK_REG(ACCEPTANCE_MASK); } if (direction == DIR_SEND) { g_TMB_INFO[mb_num].set_id = id; } return( STATUS_OK ); } void NcanEnable(uint8 no){ CANC_WR_MODE_REG(CANC_MODE_START); } void NcanDisable(uint8 no){ CANC_WR_MODE_REG(CANC_MODE_STOP); } #include "t_syslog.h" #include "t_stdlib.h" #include "sysmod/serial.h" #include "sysmod/syslog.h" STATUS NcanSetTxData(uint8 no, uint8 mb_num, uint8 id, uint8 *p_data, uint8 len){ uint8 i, j; uint32 temp_data1 = 0; /* データ(1〜4byte)格納用 */ uint32 temp_data2 = 0; /* データ(5〜8byte)格納用 */ uint32 request_bit; /* メッセージのデータが5byte以上なら、5byte目以降を先に取得する */ if (len > BYTE_LENGTH) { /* 5〜8byteのデータをコピーする */ for (i = 0U; i < (len - BYTE_LENGTH); i++) { if (i > 0U) { temp_data2 = temp_data2 << 8U; } temp_data2 = (temp_data2 | p_data[len - (1U + i)]); } } else { i = 0U; } /* メッセージのデータが1byte以上なら、1byte目以降を取得する */ if (len > 0) { /* 1〜4byteのデータをコピーする */ for (j = i; j < len; j++) { if (j > i) { temp_data1 = temp_data1 << 8U; } temp_data1 = (temp_data1 | p_data[len - (1U + j)]); } } /* CAN-IDの格納 */ CANC_WR_TXMBOX_DATA0_REG((id << EXTEND_CAN_ID_LENGTH), mb_num); /* データ長の格納 */ CANC_WR_TXMBOX_DATA1_REG(len, mb_num); if (len > 0) { /* データ(1〜4)の格納 */ CANC_WR_TXMBOX_DATA2_REG(temp_data1, mb_num); } /* データが5byte以上なら格納 */ if (len > BYTE_LENGTH) { /* データ(5〜8)の格納 */ CANC_WR_TXMBOX_DATA3_REG(temp_data2, mb_num); } SuspendAllInterrupts(); request_bit = 1U << mb_num; CANC_WR_TXREQ_REG(request_bit); ResumeAllInterrupts(); set_led7(TRUE); return( STATUS_OK ); } /* * データを受信していない場合はp_lenに0を返す */ STATUS NcanGetRxData(uint8 no, uint8 mb_num, uint8 *p_data, uint8 *p_len){ uint16 j, len; TYPE_RMB_INFO *rmb_info; rmb_info = &g_RMB_INFO[mb_num]; if( mb_num >= DEF_RMB_MAX ) { return( STATUS_ERROR ); } if( p_data == NULL ) { return( STATUS_ERROR ); } if( p_len == NULL ) { return( STATUS_ERROR ); } len = (*rmb_info).len; (*rmb_info).len = 0; for( j = 0;j < len; j++ ) { p_data[j] = (*rmb_info).data[j]; } *p_len = len; if(len != 0){ set_led0(FALSE); } return( STATUS_OK ); } static int cnt; ISR(Ncan_ISR) { uint32 irq_reg; uint32 cmp_reg; uint32 clear_bit; uint32 temp_data; uint32 i; uint32 j; uint32 wait_reg; uint8 can_dlc; irq_reg = CANC_RD_IRQ_REG(); /* 受信完了割込み */ if ((irq_reg & RECEIVE_IRQ) != 0U) { set_led0(TRUE); clear_bit = 1U; cmp_reg = CANC_RD_RXCMP_REG(); if (cmp_reg != 0U) { for (i = 0U; i < DEF_RMB_MAX; i++) { if ((cmp_reg & 1U) != 0U) { /* 対象受信ウェイトレジスタの該当するビットをウェイト処理ONにする */ wait_reg = CANC_RD_RXWAIT_REG(); wait_reg |= clear_bit; CANC_WR_RXWAIT_REG(wait_reg); /* CAN-ID取出し */ g_RMB_INFO[i].recv_id = ((CANC_RD_RXMBOX_DATA0_REG(i) & MASK_CAN_ID_MASK) >> EXTEND_CAN_ID_LENGTH); /* DLCの取り出し */ g_RMB_INFO[i].len = (uint8) (CANC_RD_RXMBOX_DATA1_REG(i) & MASK_4BIT); can_dlc = g_RMB_INFO[i].len; if (can_dlc > BYTE_LENGTH) { /* 5byte以上の場合、5byte目以降のレジスタも読み込む */ /* SDU(1〜4byte)の取り出し */ temp_data = CANC_RD_RXMBOX_DATA2_REG(i); for (j = 0U; j < BYTE_LENGTH; j++) { g_RMB_INFO[i].data[j] = (uint8) (temp_data & MASK_8BIT); temp_data >>= 8U; } /* SDU(5〜8byte)の取り出し */ temp_data = CANC_RD_RXMBOX_DATA3_REG(i); for (j = BYTE_LENGTH; j < can_dlc; j++) { g_RMB_INFO[i].data[j] = (uint8) (temp_data & MASK_8BIT); temp_data >>= 8U; } } else { /* 4byte以下の場合、5byte目以降のレジスタは読み込まない */ /* SDU(1〜4byte)の取り出し */ temp_data = CANC_RD_RXMBOX_DATA2_REG(i); for (j = 0U; j < can_dlc; j++) { g_RMB_INFO[i].data[j] = (uint8) (temp_data & MASK_8BIT); temp_data >>= 8U; } } CANC_WR_RXCMP_REG(clear_bit); /* 対象受信ウェイトレジスタの該当するビットをウェイト処理OFFにする */ wait_reg = wait_reg ^ clear_bit; CANC_WR_RXWAIT_REG(wait_reg); } cmp_reg >>= 1U; clear_bit <<= 1U; } } } /* 送信完了割込み */ if ((irq_reg & TRANSMIT_IRQ) != 0U) { set_led7(FALSE); clear_bit = 1U; cmp_reg = CANC_RD_TXCMP_REG(); if (cmp_reg != 0U) { for (i = 0U; i < DEF_TMB_MAX; i++) { if ((cmp_reg & 1U) != 0U) { CANC_WR_TXCMP_REG(clear_bit); } cmp_reg >>= 1U; clear_bit <<= 1U; } } } if ((irq_reg & 0x80) == 0x80U) { syslog(LOG_NOTICE, "NCAN : buserror! %d", cnt++); } }