Hi
I want to use 56F8037 for CAN communication between two 56F8037 EVM boards. If i download mscan_demo into flash it wont work correctly. This demo uses can buffer2 for transmitting variable lenght data through CAN bus (in main while loop), it would be after each transmittion go into interrupt service routine TXfull, but for first time it prepare data prepare buffer2 and sends but no interrupt wont come. For second time it stuck on :
while(!ioctl(MSCAN, MSCAN_SELECT_TXBUFF, MSCAN_TXBUFFER2))
;
and COP then reset mcu.
probably the buffer is still ful and no data were transmitted.
Complete demo code in attach.
THX
Hi again i have tried another setting of can bus with Quickstart no my code works perfectly in LoopBack mode but if i connect two 8037evm board together and load same codes to them program stops at line where is synchronization tested, if i disable this testing then i try to transmit data so no data are transmited and selected buffer2 is still full and interrupt TXempty is not executed.
So first problem is why node isnt synchronised with bus? And i think beacause of that transmitt buffer isnt depleted. But dont know why
THX
Code:
int main(void)
{
static UWord16 i, txlen = 4;
static UWord16* pd;
// initialize SYS, COP and pins
device_init();
// enable MSCAN
ioctl(MSCAN, MSCAN_DEVICE, MSCAN_ENABLE);
//******************************
//******************************
// enter soft-reset mode
ioctl(MSCAN, MSCAN_SLEEP, MSCAN_ON);
ioctl(MSCAN, MSCAN_SOFT_RESET, MSCAN_ENABLE);
// ...so we can continue configuration process here
ioctl(MSCAN, MSCAN_SET_ACC_MODE, MSCAN_ACC_MODE_2X32);
// open filter for standard IDs (let only lower byte matters, also IDE must be 0)
ioctl(MSCAN, MSCAN_SET_ACC_MASKR_32_0, ~(MSCAN_Id2Idr(0xff) | MSCAN_IDR_IDE));
ioctl(MSCAN, MSCAN_SET_ACC_IDR_32_0, MSCAN_Id2Idr(0x11));
// open filter for extended IDs (let only lower 22 bits matters, also IDE must be 1)
ioctl(MSCAN, MSCAN_SET_ACC_MASKR_32_1, ~(MSCAN_Id2Idr(0x803fffff) | MSCAN_IDR_IDE));
ioctl(MSCAN, MSCAN_SET_ACC_IDR_32_1, MSCAN_Id2Idr(0x80333333) | MSCAN_IDR_IDE);
// setting transfer speed and frames
ioctl(MSCAN, MSCAN_SET_CLOCK_SOURCE, MSCAN_IPBUS);
ioctl(MSCAN, MSCAN_SET_PRESCALER, 40);
ioctl(MSCAN, MSCAN_SET_SJW, MSCAN_SJW_1);
ioctl(MSCAN, MSCAN_SET_TSEG1, MSCAN_TSEG_8);
ioctl(MSCAN, MSCAN_SET_TSEG2, MSCAN_TSEG_7);
ioctl(MSCAN, MSCAN_SET_SAMPLING, MSCAN_3SAMPS_PER_BIT);
// wake-up filter
ioctl(MSCAN, MSCAN_WAKEUP_FILTER, MSCAN_DISABLE);
// boot off recovery
ioctl(MSCAN, MSCAN_MANUAL_BOFF_RECOVERY, MSCAN_DISABLE);
// loopback mode
ioctl(MSCAN, MSCAN_LOOPBACK_MODE, MSCAN_DISABLE);
// listen only mode
ioctl(MSCAN, MSCAN_LISTEN_ONLY_MODE, MSCAN_DISABLE);
// exit soft-reset mode
ioctl(MSCAN, MSCAN_SLEEP, MSCAN_OFF);
ioctl(MSCAN, MSCAN_SOFT_RESET, MSCAN_DISABLE);
//******************************
//******************************
// now can configure CAN
ioctl(MSCAN, MSCAN_STOP_IN_WAIT, MSCAN_DISABLE);
ioctl(MSCAN, MSCAN_TIMESTAMP_TIMER, MSCAN_DISABLE);
ioctl(MSCAN, MSCAN_AUTO_WAKEUP, MSCAN_DISABLE);
// now we can enable MSCAN interrupts (reset must be off)
ioctl(MSCAN, MSCAN_ERINT_SET_RSTATE_MODE, MSCAN_STAT_ALL);
ioctl(MSCAN, MSCAN_ERINT_SET_TSTATE_MODE, MSCAN_STAT_ALL);
ioctl(MSCAN, MSCAN_ERINT_DISABLE, MSCAN_STATCHNG | MSCAN_OVERRUN | MSCAN_WAKEUP);
// enable interrupts
ioctl(INTC, INTC_INIT, NULL);
archEnableInt();
// switch to transmit buffer 2
while(!ioctl(MSCAN, MSCAN_SELECT_TXBUFF, MSCAN_TXBUFFER2))
;
// prepare Transmit buffer 2 to periodically transmit in the loop bellow
ioctl(MSCAN_TB, MSCANMB_SET_ID, 0x333333 | MSCAN_ID_EXT);
// data pointer
pd = ioctl(MSCAN_TB, MSCANMB_GET_DATAPTR, NULL);
// initialize data for periodical transmission
// (each 16bit word contains a single data byte)
pd[0] = 0x11;
pd[1] = 0x22;
pd[2] = 0x33;
pd[3] = 0x44;
pd[4] = 0x55;
pd[5] = 0x66;
pd[6] = 0x77;
pd[7] = 0x88;
// while(!ioctl(MSCAN, MSCAN_TEST_SYNCH, NULL))
// ;
// do forever
while(1)
{
/* disable RX interrupt which also touches the TX buffer selection */
ioctl(MSCAN, MSCAN_ERINT_DISABLE, MSCAN_RXFULL);
/* switch to transmit buffer 2 (also waits until this buffer is empty) */
while(!ioctl(MSCAN, MSCAN_SELECT_TXBUFF, MSCAN_TXBUFFER2))
;
ioctl(MSCAN_TB, MSCANMB_SET_LEN, txlen);
/* re-enable receiver interrupt */
ioctl(MSCAN, MSCAN_ERINT_ENABLE, MSCAN_RXFULL);
/* transmit frame buffer 2 */
ioctl(MSCAN, MSCAN_TRANSMIT, MSCAN_TXBUFFER2);
ioctl(MSCAN, MSCAN_TINT_ENABLE, MSCAN_TXBUFFER2);
// if(++txlen > 8)
// txlen = 1;
// wait a while
for(i=0; i<50; i++)
{
ioctl(COP, COP_CLEAR_COUNTER, NULL);
archDelay(0xffff);
}
}
}
void MSCAN_ErrorISR(void)
{
#pragma interrupt saveall
register UWord16 err = ioctl(MSCAN, MSCAN_READ_EINT_FLAGS, NULL);
ioctl(MSCAN, MSCAN_CLEAR_EINT_FLAGS, err);
}
void MSCAN_WakeUpISR(void)
{
#pragma interrupt saveall
ioctl(MSCAN, MSCAN_CLEAR_WINT_FLAG, NULL);
}
void MSCAN_RxFullISR(void)
{
#pragma interrupt saveall
register UWord32 id = ioctl(MSCAN_RB, MSCANMB_GET_ID, NULL);
register UWord16 len = ioctl(MSCAN_RB, MSCANMB_GET_LEN, NULL);
register UWord16 isRTR = ioctl(MSCAN_RB, MSCANMB_GET_RTR, NULL);
volatile UWord16 winf = ioctl(MSCAN, MSCAN_GET_WINNING_ACC_FILTER, NULL);
ioctl(GPIO_LED_G2, GPIO_TOGGLE_PIN, LED_G2);
// respond to non-RTR 0x11 frames only
if(id == 0x11 && !isRTR)
{
/* use buffer 0 or 1 to send response back */
UWord16 txbuff = ioctl(MSCAN, MSCAN_SELECT_TXBUFF, MSCAN_TXBUFFER0 | MSCAN_TXBUFFER1);
/* have free buffer (either 0 or 1) */
if(txbuff)
{
register UWord16* pdR = ioctl(MSCAN_RB, MSCANMB_GET_DATAPTR, NULL);
register UWord16* pdT = ioctl(MSCAN_TB, MSCANMB_GET_DATAPTR, NULL);
// copy data (don't need to check the len)
pdT[0] = pdR[0];
pdT[1] = pdR[1];
pdT[2] = pdR[2];
pdT[3] = pdR[3];
pdT[4] = pdR[4];
pdT[5] = pdR[5];
pdT[6] = pdR[6];
pdT[7] = pdR[7];
// prepare ID (extended), LEN
ioctl(MSCAN_TB, MSCANMB_SET_ID, 0x1111 | MSCAN_ID_EXT);
ioctl(MSCAN_TB, MSCANMB_SET_LEN, len);
// transmit buffer
ioctl(MSCAN, MSCAN_TRANSMIT, txbuff);
ioctl(GPIO_LEDS, GPIO_TOGGLE_PIN, LED_R);
// enable tx-finished interrupt
ioctl(MSCAN, MSCAN_TINT_ENABLE, txbuff);
}
}
// LED responds to non-RTR ext 0x333333 frames only
if(id == 0x80333333 && !isRTR)
{
ioctl(GPIO_LEDS, GPIO_TOGGLE_PIN, LED_G);
}
// clear interrupt flag
ioctl(MSCAN, MSCAN_CLEAR_RINT_FLAG, NULL);
}
void MSCAN_TxRdyISR(void)
{
#pragma interrupt saveall
/* what tx buffers are empty? */
UWord16 tint = ioctl(MSCAN, MSCAN_READ_TINT_FLAGS, NULL);
/* only consider buffers recently sent */
tint &= ioctl(MSCAN, MSCAN_GET_ENABLED_TINT, NULL);
if(tint & MSCAN_TXBUFFER2)
ioctl(GPIO_LEDS, GPIO_TOGGLE_PIN, LED_Y2);
if(tint & ~(MSCAN_TXBUFFER2))
ioctl(GPIO_LEDS, GPIO_TOGGLE_PIN, LED_Y);
/* disable interrupts handled */
ioctl(MSCAN, MSCAN_TINT_DISABLE, tint);
}
/*
* Initialize SYS and all GPIO modules.
*/
void device_init(void)
{
ioctl(SYS, SYS_INIT, NULL);
ioctl(COP, COP_INIT, NULL);
/* Note: This code is targeted to all 56F8xxx-based evaluation boards.
So we need to check what GPIO instances are actually implemented */
#ifdef GPIO_A
ioctl(GPIO_A, GPIO_INIT, NULL);
#endif
#ifdef GPIO_B
ioctl(GPIO_B, GPIO_INIT, NULL);
#endif
#ifdef GPIO_C
ioctl(GPIO_C, GPIO_INIT, NULL);
#endif
#ifdef GPIO_D
ioctl(GPIO_D, GPIO_INIT, NULL);
#endif
#ifdef GPIO_E
ioctl(GPIO_E, GPIO_INIT, NULL);
#endif
#ifdef GPIO_F
ioctl(GPIO_F, GPIO_INIT, NULL);
#endif
}