Hi all,
I'm trying to setup a CAN bus using a MC9S08DZ60 and the msCAN08 driver. I have an 8MHz resonator and have msCAN08 configured (I think) for 250kbps, where the msCAN module is fed directly from the resonator. The config portion is below:
/*===========================================================================
Define S08 msCAN module clock source: BUSCLK or MCGERCLK
Permitted values: BUSCLK: Bus clock is used as clock source
MCGERCLK: Oscillator clock is used as clock source
===========================================================================*/
#define CLKSRC_CAN MCGERCLK
/*===========================================================================
Define clock prescaler for msCAN module: permitted values 1 to 64
msCAN module clock = CLKSRC_CAN / PRESCALER_CAN
===========================================================================*/
#define PRESCALER_CAN 4
/*===========================================================================
Define msCAN module bit timing
Permitted values: PROP_SEG_CAN: 1 to 8 time quanta
PHASE_SEG1_CAN: 1 to 8 time quanta
PHASE_SEG2_CAN: 2, or PHASE_SEG1_CAN if greater
Bit time = (SYNC_SEG + PROP_SEG_CAN + PHASE_SEG1_CAN + PHASE_SEG2_CAN) * time quanta
SYNC_SEG is always 1
Tq = 500nS with msCAN module fed from an 8MHz resonator, prescaler = 4
Bit time = (1 + 1 + 3 + 3)*500nS = 250kbps
===========================================================================*/
#define PROP_SEG_CAN 1
#define PHASE_SEG1_CAN 3
#define PHASE_SEG2_CAN 3
/*===========================================================================
Define msCAN module re-synchronisation jump width
Permitted values: 1 to smaller of 4 and PHASE_SEG1_CAN time quanta
===========================================================================*/
#define RJW_CAN 3
/*==========================================================================*/
Problem is everytime I attempt to transmit I get a sync error, and see nothing on the scope.
Questions is given I need a 250kbps bus speed, do the settings above make sense?
Thanks in advance,
Tim
已解决! 转到解答。
Well I feel stupid. Turns out the problem was caused from an uninitialized index.
In msCANreg.h the CAN registers are defined via a reference off CAN_BaseAddress:
/******************************************************************************
* msCAN module registers
******************************************************************************/
#define CANCTL0 (*((volatile UINT8 *const)(CAN_BaseAddress)))
#define CANCTL1 (*((volatile UINT8 *const)(CAN_BaseAddress + 0x01)))
I forgot to define it! Duh!
However, the changes discussed in previous posts did need to be made. Everything works fine now! Thanks for all the help!
After further digging I'm finding the CAN bus isn't initializing properly at startup. Freescale's CAN_Init function first calls a CAN_Reset function to soft reset the msCAN module. Below is a snippet of the first few lines of this function.
UINT8 CAN_Reset(UINT8 rmode)
{
if (CANCTL1 & INITAK) return ERR_OK;
if (CANCTL0 & INITRQ) return ERR_INIT;
if (!((rmode == FAST) || (rmode == CMPTX)))
{
return (ERR_MODE);
}
This routine is called right out of reset AFTER initializing the system options register and clocks. When it gets to the line in bold, it returns from the function and the CANCTL and config registers never get set.
Now I need to figure out why the msCAN module is NOT in initialization mode right out of reset.
After reading some additional posts I modified the code to do the following:
if (! (CANCTL0 & INITRQ)) /* If not in init mode */
CANCTL0 |= INITRQ; /* Enter MSCAN initialization mode */
while (!(CANCTL1 & INITAK)); /* Wait until the MSCAN is in initialization mode */
However the micro never will enter init mode and it loops endlessly on the while statement.
Any ideas?
Thanks for all the replies.
Yes the CANE bit is enabled just prior to the code snippet. Here is the whole section:
UINT8 CAN_Reset(UINT8 rmode)
{
CANCTL1 |= 0x80; /* Enable CAN (CANE bit) */
if (! (CANCTL0 & INITRQ)) /* If not in init mode */
CANCTL0 |= INITRQ; /* Enter MSCAN initialization mode */
while (!(CANCTL1 & INITAK)); /* Wait until the MSCAN is in initialization mode */
Hm, it should pass INITAK loop. Is oscilator enabled and operating prior to CAN_Reset() call?
Another reason to refuse to send may be LISTEN bit. It is set by default.
It is not cleat what's INITAK. Codewarrior headers don't have it defined. Is it bitmask or bit from CANCTL1 bitfield?
Per your suggestion I added a line to clear the LISTEN bit, but it still gets stuck in the INITAK loop.
INITAK is defined as 0x01.
Yes the oscillator is up and running prior to this. All my timer interrupts are working fine. However I'm beginning to think this problem is clock related. I have the MCGERCLK enabled and am using that to feed the MSCAN module directly (CLKSRC bit in CANCTL1 set to 0). My timers all run off the PLL though.
Well I feel stupid. Turns out the problem was caused from an uninitialized index.
In msCANreg.h the CAN registers are defined via a reference off CAN_BaseAddress:
/******************************************************************************
* msCAN module registers
******************************************************************************/
#define CANCTL0 (*((volatile UINT8 *const)(CAN_BaseAddress)))
#define CANCTL1 (*((volatile UINT8 *const)(CAN_BaseAddress + 0x01)))
I forgot to define it! Duh!
However, the changes discussed in previous posts did need to be made. Everything works fine now! Thanks for all the help!