CCS: Version: 6.1.2.00015
Tiva Eval Board: EK_TM4C1294XL
TivaWare_C_Series-2.1.2.111
xdctools_3_31_01_33_core
Wanting to use a SPI serial flash chip in our project. Using an eval board as a testbed prior to having
our initial prototype built.
I put the serial flash chip on a protoboard and connected it to the booster pack #2 bus. The pins were
setup to use the second SPI channel (Board_SPI1) which corresponds to SSI #3 on the CPU.
First I took the 'SPI Loopback' example and modified it so I could demonstrate that I could communicate
with the device. I both wrote data and read it back. Well and good.
Then I wanted to take my learnings and add SPI communication to my already existing much larger application
also running on the same eval board.
I carefully examined the .cfg file for the SPI Looback example and the only thing I could find that seemed
to be different was the line:
TIRTOS.useSPI = true;
So I added this line to my config file and included "ti/drivers/SPI.h" in my source file.
Executing the following sequence:
SPI_Params_init(&spi_params);
spi_params.bitRate = 10000000; // 10 megabit data rate
spi_params.frameFormat = SPI_POL1_PHA1; // This is the mode that works with the serial flash
spi_handle = SPI_open(Board_SPI1, &spi_params);
The program crashes during the SPI_open function. According to the console output at the time of
the crash, it is aborting on the first assembly line of function "SSIIntDisable()" called from
"SPITivaDMA_open()".
I have verified that the working SPI Loopback derivation goes through the same line without failing.
Is there some other change I need to make to the project to enable SSI/SPI operation?
Below is the .cfg file (header comments excluded) on the larger application that fails to open the SPI channel:
var Defaults = xdc.useModule('xdc.runtime.Defaults');
var Diags = xdc.useModule('xdc.runtime.Diags');
var Error = xdc.useModule('xdc.runtime.Error');
var Log = xdc.useModule('xdc.runtime.Log');
var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
var Memory = xdc.useModule('xdc.runtime.Memory');
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var System = xdc.useModule('xdc.runtime.System');
var Timestamp = xdc.useModule('xdc.runtime.Timestamp');
var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
var Idle = xdc.useModule('ti.sysbios.knl.Idle');
var Task = xdc.useModule('ti.sysbios.knl.Task');
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
var Timer = xdc.useModule('ti.sysbios.family.arm.lm4.Timer');
var Mailbox = xdc.useModule('ti.sysbios.knl.Mailbox');
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
var Startup = xdc.useModule('xdc.runtime.Startup');
var Seconds = xdc.useModule('ti.sysbios.hal.Seconds');
/*
* Uncomment this line to globally disable Asserts.
* All modules inherit the default from the 'Defaults' module. You
* can override these defaults on a per-module basis using Module.common$.
* Disabling Asserts will save code space and improve runtime performance.
Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
*/
/*
* Uncomment this line to keep module names from being loaded on the target.
* The module name strings are placed in the .const section. Setting this
* parameter to false will save space in the .const section. Error and
* Assert messages will contain an "unknown module" prefix instead
* of the actual module name.
Defaults.common$.namedModule = false;
*/
/*
* Minimize exit handler array in System. The System module includes
* an array of functions that are registered with System_atexit() to be
* called by System_exit().
*/
System.maxAtexitHandlers = 4;
/*
* Uncomment this line to disable the Error print function.
* We lose error information when this is disabled since the errors are
* not printed. Disabling the raiseHook will save some code space if
* your app is not using System_printf() since the Error_print() function
* calls System_printf().
Error.raiseHook = null;
*/
/*
* Uncomment this line to keep Error, Assert, and Log strings from being
* loaded on the target. These strings are placed in the .const section.
* Setting this parameter to false will save space in the .const section.
* Error, Assert and Log message will print raw ids and args instead of
* a formatted message.
Text.isLoaded = false;
*/
/*
* Uncomment this line to disable the output of characters by SysMin
* when the program exits. SysMin writes characters to a circular buffer.
* This buffer can be viewed using the SysMin Output view in ROV.
SysMin.flushAtExit = false;
*/
/*
* The BIOS module will create the default heap for the system.
* Specify the size of this default heap.
*/
BIOS.heapSize = 65536;
/*
* Build a custom SYS/BIOS library from sources.
*/
BIOS.libType = BIOS.LibType_NonInstrumented;
/*
* Program.stack is ignored with IAR. Use the project options in
* IAR Embedded Workbench to alter the system stack size.
*/
if (!Program.build.target.$name.match(/iar/)) {
/*
* Reducing the system stack size (used by ISRs and Swis) to reduce
* RAM usage.
*/
Program.stack = 2048;
}
/* Enable Semihosting for GNU targets to print to CCS console */
if (Program.build.target.$name.match(/gnu/)) {
}
/* Circular buffer size for System_printf() */
SysMin.bufSize = 0x400;
/* ================ Driver configuration ================ */
var TIRTOS = xdc.useModule('ti.tirtos.TIRTOS');
TIRTOS.useGPIO = true;
TIRTOS.useSPI = true;
var task0Params = new Task.Params();
task0Params.instance.name = "UartTaskHandle";
task0Params.arg0 = 0;
task0Params.priority = 8;
task0Params.stackSize = 1024;
Program.global.UartTaskHandle = Task.create("&Uart_Task", task0Params);
System.SupportProxy = SysMin;
/*
var log0Params = new LoggerBuf.Params();
log0Params.instance.name = "systemLog";
log0Params.exitFlush = true;
log0Params.numEntries = 16;
Program.global.systemLog = LoggerBuf.create(log0Params);
Defaults.common$.logger = Program.global.systemLog;
Defaults.common$.diags_INFO = Diags.ALWAYS_ON;
Defaults.common$.diags_USER1 = Diags.ALWAYS_OFF;
*/
Idle.addFunc("&clockIdle");
var timer0Params = new Timer.Params();
timer0Params.instance.name = "SensorTimerHandle";
timer0Params.period = 30719;
timer0Params.startMode = xdc.module("ti.sysbios.interfaces.ITimer").StartMode_USER;
timer0Params.runMode = xdc.module("ti.sysbios.interfaces.ITimer").RunMode_CONTINUOUS;
timer0Params.altclk = false;
timer0Params.periodType = xdc.module("ti.sysbios.interfaces.ITimer").PeriodType_COUNTS;
Program.global.SensorTimerHandle = Timer.create(null, "&ReadLastSensorConversion", timer0Params);
Task.idleTaskStackSize = 1024;
var task1Params = new Task.Params();
task1Params.instance.name = "MainLoopTaskHandle";
task1Params.stackSize = 16384;
Program.global.MainLoopTaskHandle = Task.create("&main_loop_task", task1Params);
var clock0Params = new Clock.Params();
clock0Params.instance.name = "KernelClock";
clock0Params.startFlag = true;
clock0Params.period = 100;
Program.global.KernelClock = Clock.create("&KernelTick", 1000, clock0Params);
Clock.swiPriority = 8;
var mailbox0Params = new Mailbox.Params();
mailbox0Params.instance.name = "KickBox";
Program.global.KickBox = Mailbox.create(8, 50, mailbox0Params);
Clock.tickPeriod = 1000;
var task2Params = new Task.Params();
task2Params.instance.name = "DiscriminatorTaskHandle";
task2Params.priority = 13;
task2Params.stackSize = 4096;
Program.global.DiscriminatorTaskHandle = Task.create("&DiscriminatorTask", task2Params);
var task3Params = new Task.Params();
task3Params.instance.name = "KickTaskHandle";
task3Params.priority = 14;
task3Params.stackSize = 1024;
Program.global.KickTaskHandle = Task.create("&KickTask", task3Params);
var timer1Params = new Timer.Params();
timer1Params.instance.name = "StartKickHandle";
timer1Params.runMode = xdc.module("ti.sysbios.interfaces.ITimer").RunMode_CONTINUOUS;
timer1Params.startMode = xdc.module("ti.sysbios.interfaces.ITimer").StartMode_USER;
timer1Params.period = 100;
Program.global.StartKickHandle = Timer.create(1, "&StartKick", timer1Params);
var timer2Params = new Timer.Params();
timer2Params.instance.name = "StopKickHandle";
timer2Params.startMode = xdc.module("ti.sysbios.interfaces.ITimer").StartMode_USER;
timer2Params.runMode = xdc.module("ti.sysbios.interfaces.ITimer").RunMode_CONTINUOUS;
timer2Params.period = 100;
timer2Params.altclk = false;
Program.global.StopKickHandle = Timer.create(2, "&StopKick", timer2Params);
var task4Params = new Task.Params();
task4Params.instance.name = "SolenoidPulseOffTaskHandle";
task4Params.priority = 6;
task4Params.stackSize = 1024;
Program.global.SolenoidPulseOffTaskHandle = Task.create("&SolenoidPulseOffTask", task4Params);
var semaphore0Params = new Semaphore.Params();
semaphore0Params.instance.name = "KickCompleteSemHandle";
semaphore0Params.mode = Semaphore.Mode_BINARY;
Program.global.KickCompleteSemHandle = Semaphore.create(1, semaphore0Params);
var semaphore1Params = new Semaphore.Params();
semaphore1Params.instance.name = "SolenoidPulseOffSemHandle";
semaphore1Params.mode = Semaphore.Mode_BINARY;
Program.global.SolenoidPulseOffSemHandle = Semaphore.create(null, semaphore1Params);
var clock1Params = new Clock.Params();
clock1Params.instance.name = "DiscriminatorClockHandle";
clock1Params.period = 5;
Program.global.DiscriminatorClockHandle = Clock.create("&DiscriminatorClockTick", 5, clock1Params);
var semaphore2Params = new Semaphore.Params();
semaphore2Params.instance.name = "RunDiscriminatorTask";
semaphore2Params.mode = Semaphore.Mode_BINARY;
Program.global.RunDiscriminatorTask = Semaphore.create(null, semaphore2Params);
var clock2Params = new Clock.Params();
clock2Params.instance.name = "RailRakeMonitorHandle";
clock2Params.period = 1;
Program.global.RailRakeMonitorHandle = Clock.create("&RailRakeMonitor", 1, clock2Params);
BIOS.customCCOpts = "--endian=little -mv7M4 --abi=eabi --float_support=fpv4spd16 -q -ms --opt_for_speed=2 --program_level_compile -o3 -g --optimize_with_debug";
BIOS.logsEnabled = false;
BIOS.assertsEnabled = false;
Defaults.common$.diags_INTERNAL = Diags.ALWAYS_OFF;
Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
Hwi.dispatcherIrpTrackingSupport = true;
var task5Params = new Task.Params();
task5Params.instance.name = "UserButtonTaskHandle";
task5Params.priority = 4;
task5Params.stackSize = 1024;
Program.global.UserButtonTaskHandle = Task.create("&UserButtonTask", task5Params);
var task6Params = new Task.Params();
task6Params.instance.name = "DeadmanTaskHandle";
task6Params.priority = 9;
task6Params.stackSize = 1024;
Program.global.DeadmanTaskHandle = Task.create("&DeadmanTask", task6Params);
var task7Params = new Task.Params();
task7Params.instance.name = "SerialFlashTaskHandle";
task7Params.priority = 2;
Program.global.SerialFlashTaskHandle = Task.create("&SerialFlashTask", task7Params);