Hi, Everybody!
I'm trying to bring up code on the '28030 Piccolo. My CAN initialization is heavily modeled after years of successful practice on the '2801.
But it's not working. As I assign eCAN A its pins (GPIO30 and GPIO31), the CANTXA output on GPIO31 goes low and stays there. The eCAN controller doesn't start correctly because it's keeping itself from ever seeing a recessive bit.
Why?
The initialization goes like this:
void main(void)
{
// Get the brownout reset and watchdog timer functions on the air.
InitializeWatchdog();
// Take an immediate reset on clock failure, leave the crystal oscillator
// running, turn off the external clock input, turn off internal oscillator 2,
// keep internal oscillator running should the processor go into HALT mode,
// leave the watchdog timer on internal oscillator 1, and leave the processor
// running on internal oscillator 1 for now.
EALLOW;
SysCtrlRegs.CLKCTL.all = 0x3E00;
// Disable the external clock output.
SysCtrlRegs.XCLK.all = 0x0003;
EDIS;
// Wait 10 ms for the 8 MHz crystal oscillator to start.
CpuTimer2Regs.TCR.all = 0x8810;
CpuTimer2Regs.PRD.all = 100000UL;
ReloadCpuTimer2();
StartCpuTimer2();
while (!CpuTimer2Regs.TCR.bit.TIF);
// Switch the processor over to the crystal oscillator.
EALLOW;
SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1;
// Put back the divide-by-4 that the boot ROM took out, get the PLL up to 56
// MHz, wait for the PLL to lock, then pull out the divide-by-4.
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS) ResetCPU();
SysCtrlRegs.PLLSTS.all = 0x8040;
SysCtrlRegs.PLLLOCKPRD = 2000;
SysCtrlRegs.PLLCR.all = 7;
EDIS;
asm("\tNOP");
while (!SysCtrlRegs.PLLSTS.bit.PLLLOCKS);
EALLOW;
SysCtrlRegs.PLLSTS.all = 0x8180;
// Set the low-speed peripheral clock to 28 MHz then feed clocks to CPU timer
// 0, I2C A, ePWM 1, HRPWM, eCAN A, and the GPIO module.
SysCtrlRegs.LOSPCP.all = 2 / 2;
SysCtrlRegs.PCLKCR0.all = 0x4015;
SysCtrlRegs.PCLKCR1.all = 0x0001;
SysCtrlRegs.PCLKCR3.all = 0x2100;
EDIS;
// Bring the flash and OTP wait states down to minimums.
memcpy(RAMImage,FlashImage,sizeof(FlashImage));
SetWaitStates();
// Kick the dog to allow for the 11 ms we've burned getting the clock running.
ServiceWatchdog();
// Initialize the rest of the peripherals.
InitializeInterrupts();
InitializeBinaryIO();
InitializeCANController();
// Snip off the rest of main() since the problem has already occurred.
And InitializeCANController() starts like this:
void InitializeCANController(void)
{
// Give the CAN controller its I/O pins, set it up, and start it.
EALLOW;
ECanaRegs.CANTIOC.all = 0x00000004UL;
ECanaRegs.CANRIOC.all = 0x00000004UL;
GpioCtrlRegs.GPAMUX2.all &= 0x5FFFFFFFUL;
GpioCtrlRegs.GPAMUX2.all |= 0x50000000UL;
ECanaRegs.CANBTC.all = (14UL - 1 << 16) | (1 - 0 << 8) | (0 << 7) | (12 - 1 << 3) | (3 - 1 << 0);
ECanaRegs.CANMC.all = 0x00013080UL;
ECanaRegs.CANMC.all = 0x00012080UL;
EDIS;
// Snip off the part where I actually set up the mailboxes as the problem has already occurred.
Right after the OR onto GPAMUX2, the CANTXA output goes low and stays there. That's not what happens on the '2801.
Any ideas?
Will