Hello,
I try to tesst my programm with the True time simulator.
However after sbufferpos = 15 (after 15 times ISR_Interrupt) some parts of the buffer array will be overwritten.
Then there occurs an error:
Error: At location 0057 -
Error: Attempt to execute from unimplemented (--) ROM
Do you have any idea how to fix this problem?
// Includes ----------------------------------------------------------------------------------------
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "SPIDriver.h"
// Variablen ---------------------------------------------------------------------------------------
static volatile int sbufferpos = 0;
byte buffer[33];
// Prototypen --------------------------------------------------------------------------------------
void BefehlsbufferErstellen(int takt);
void SendeBuffer(byte b);
// Main --------------------------------------------------------------------------------------------
void main(void) {
spi_init();
spi_setMode(Master, FallingEdge, LeadingEdge, MSBfirst);
spi_selectChip(true,0);
BefehlsbufferErstellen(27);
spi_enableInterrupt(true);
for(;;)
{
__RESET_WATCHDOG();
}
}
// Interruptroutinen ---------------------------------------------------------------------------------
__interrupt VectorNumber_Vspi1 void ISR_SPI() {
if((SPI1S&(SPI1S_SPRF_MASK)) == 0) {
}
else{
SPI1S;
SPI1D;
}
if((SPI1S&(SPI1S_SPTEF_MASK)) == 0){
}
else{
spi_enableInterrupt(false);
if(sbufferpos > sizeof(buffer) - 1) {
sbufferpos = 0;
} else{
SendeBuffer(buffer[sbufferpos]);
sbufferpos++;
spi_enableInterrupt(true);
}
}
}
// Funktionen -----------------------------------------------------------------------------------------
void BefehlsbufferErstellen (int takt) {
if(takt== 27) {
buffer[0]= 0x9F; // Set Address
buffer[1]= 0x24; // 36d
buffer[2]= 0x40; // Write
buffer[3]= 0x4F; // 4Fh
buffer[4]= 0x9F; // Set Address
buffer[5]= 0x28; // 40d
buffer[6]= 0x40; // Write
buffer[7]= 0x00; // 00h
buffer[8]= 0x9F; // Set Address
buffer[9]= 0x29; // 41d
buffer[10]= 0x40; // Write
buffer[11]= 0x02; // 02h
buffer[12]= 0x9F; // Set Address
buffer[13]= 0x30; // 42d
buffer[14]= 0x40; // Write
buffer[15]= 0x9F; // 0x9Fh
buffer[16]= 0x9F; // Set Address
buffer[17]= 0x32; // 44d
buffer[18]= 0x40; // Write
buffer[19]= 0x00; // 00h
buffer[20]= 0x9F; // Set Address
buffer[21]= 0x33; // 45d
buffer[22]= 0x40; // Write
buffer[23]= 0x0D; // 0Dh
buffer[24]= 0x9F; // Set Address
buffer[25]= 0x35; // 47d
buffer[26]= 0x40; // Write
buffer[27]= 0x00; // 00h
buffer[28]= 0x9F; // Set Address
buffer[29]= 0x36; // 48d
buffer[30]= 0x40; // Write
buffer[31]= 0x0D; // 0Dh
}
else if(takt == 26){
buffer[0]= 0x9F; // Set Address
buffer[1]= 0x24; // 36d
buffer[2]= 0x40; // Write
buffer[3]= 0x3D; // 3Dh
buffer[4]= 0x9F; // Set Address
buffer[5]= 0x28; // 40d
buffer[6]= 0x40; // Write
buffer[7]= 0x20; // 20h
buffer[8]= 0x9F; // Set Address
buffer[9]= 0x29; // 41d
buffer[10]= 0x40; // Write
buffer[11]= 0x95; // 95h
buffer[12]= 0x9F; // Set Address
buffer[13]= 0x30; // 42d
buffer[14]= 0x40; // Write
buffer[15]= 0xFF; // FFh
buffer[16]= 0x9F; // Set Address
buffer[17]= 0x32; // 44d
buffer[18]= 0x40; // Write
buffer[19]= 0x03; // 03h
buffer[20]= 0x9F; // Set Address
buffer[21]= 0x33; // 45d
buffer[22]= 0x40; // Write
buffer[23]= 0xE8; // E8h
buffer[24]= 0x9F; // Set Address
buffer[25]= 0x35; // 47d
buffer[26]= 0x40; // Write
buffer[27]= 0x03; // 03h
buffer[28]= 0x9F; // Set Address
buffer[29]= 0x36; // 48d
buffer[30]= 0x40; // Write
buffer[31]= 0xE8; // E8h
}
else {
}
}
void SendeBuffer(byte b) {
__RESET_WATCHDOG();
spi_sendData(b);
}
Solved! Go to Solution.
Hello,
These symptoms would indicate a stack overflow problem. It may be possible that you have an unintended nested interrupt situation. The spi_enableInterrupt() function might be a possible cause, if it is globally enabling interrupts within the ISR function. The use of this function within the ISR would seem unnecessary, except for the final disable of the SPI interrupt when the data sequence is completed. I would also suspect that you have the SPTEF interrupt enabled, which will exacerbate the problem.
If you wish to use interrupts for SPI master operation, only the RDRF interrupt should be enabled - the SPTEF interrupt should remain disabled. When the RDRF flag becomes set, this means that the transfer of the last send byte has been completed, and the next byte may now be sent after the RDRF flag has been cleared. It is not necessary to test the SPTEF flag.
I assume that the spi_selectChip() function is simply enabling the CS signal to the external device. You do not appear to be disabling the signal after completion of the send sequence. Since the data sequence is loaded byte-by-byte into the array variable, this would seem very inefficient. An alternative method would be to create constant array variables directly within flash memory. The data can then be accessed using a pointer variable, without the need for using an array variable. The following code snippet shows this approach.
//-----------------------------------------------------------------------------
// Global variables:
volatile byte *pntr;
volatile byte buf_count;
//-----------------------------------------------------------------------------
// Data sequence tables:
const byte data_seq1[] = {
0x9F, 0x24, 0x40, 0x4F,
0x9F, 0x28, 0x40, 0x00,
0x9F, 0x29, 0x40, 0x02,
0x9F, 0x30, 0x40, 0x9F,
0x9F, 0x32, 0x40, 0x00,
0x9F, 0x33, 0x40, 0x0D,
0x9F, 0x35, 0x40, 0x00,
0x9F, 0x36, 0x40, 0x0D
};
const byte data_seq2[] = {
0x9F, 0x24, 0x40, 0x3D,
0x9F, 0x28, 0x40, 0x20,
0x9F, 0x29, 0x40, 0x95,
0x9F, 0x30, 0x40, 0xFF,
0x9F, 0x32, 0x40, 0x03,
0x9F, 0x33, 0x40, 0xE8,
0x9F, 0x35, 0x40, 0x03,
0x9F, 0x36, 0x40, 0xE8
};
//-----------------------------------------------------------------------------
void main(void)
{
SPI_init();
EnableInterrupts; // Globally enable interrupts
SPI_selectChip( true, 0); // Enable SPI slave device
SPI_send_start( 27); // Start send sequence
while (buf_count) // Wait until send sequence completed
__RESET_WATCHDOG();
SPI_selectChip( false, 0); // Disable SPI slave device
for( ; ; ) {
__RESET_WATCHDOG();
}
}
//-----------------------------------------------------------------------------
// Start SPI send sequence
void SPI_send_start( byte takt)
{
if (takt == 27) pntr = data_seq1;
if (takt == 26) pntr = data_seq2;
if (takt) {
while (SPI1S_SPTEF == 0);
SPI1D = *pntr++; // Send first byte of sequence
buf_count = 31;
SPI_Interrupt( true); // Enable SPRF interrupts
}
else buf_count = 0;
}
//-----------------------------------------------------------------------------
// Interrupt functions:
__interrupt VectorNumber_Vspi1
void ISR_SPI( void)
{
(void)SPI1S; // Clear SPRF flag
(void)SPI1D;
if (buf_count) {
SPI1D = *pntr++;
buf_count--;
}
else
SPI_Interrupt( false); // Disable SPI interrupts
}
Regards,
Mac
Hello,
These symptoms would indicate a stack overflow problem. It may be possible that you have an unintended nested interrupt situation. The spi_enableInterrupt() function might be a possible cause, if it is globally enabling interrupts within the ISR function. The use of this function within the ISR would seem unnecessary, except for the final disable of the SPI interrupt when the data sequence is completed. I would also suspect that you have the SPTEF interrupt enabled, which will exacerbate the problem.
If you wish to use interrupts for SPI master operation, only the RDRF interrupt should be enabled - the SPTEF interrupt should remain disabled. When the RDRF flag becomes set, this means that the transfer of the last send byte has been completed, and the next byte may now be sent after the RDRF flag has been cleared. It is not necessary to test the SPTEF flag.
I assume that the spi_selectChip() function is simply enabling the CS signal to the external device. You do not appear to be disabling the signal after completion of the send sequence. Since the data sequence is loaded byte-by-byte into the array variable, this would seem very inefficient. An alternative method would be to create constant array variables directly within flash memory. The data can then be accessed using a pointer variable, without the need for using an array variable. The following code snippet shows this approach.
//-----------------------------------------------------------------------------
// Global variables:
volatile byte *pntr;
volatile byte buf_count;
//-----------------------------------------------------------------------------
// Data sequence tables:
const byte data_seq1[] = {
0x9F, 0x24, 0x40, 0x4F,
0x9F, 0x28, 0x40, 0x00,
0x9F, 0x29, 0x40, 0x02,
0x9F, 0x30, 0x40, 0x9F,
0x9F, 0x32, 0x40, 0x00,
0x9F, 0x33, 0x40, 0x0D,
0x9F, 0x35, 0x40, 0x00,
0x9F, 0x36, 0x40, 0x0D
};
const byte data_seq2[] = {
0x9F, 0x24, 0x40, 0x3D,
0x9F, 0x28, 0x40, 0x20,
0x9F, 0x29, 0x40, 0x95,
0x9F, 0x30, 0x40, 0xFF,
0x9F, 0x32, 0x40, 0x03,
0x9F, 0x33, 0x40, 0xE8,
0x9F, 0x35, 0x40, 0x03,
0x9F, 0x36, 0x40, 0xE8
};
//-----------------------------------------------------------------------------
void main(void)
{
SPI_init();
EnableInterrupts; // Globally enable interrupts
SPI_selectChip( true, 0); // Enable SPI slave device
SPI_send_start( 27); // Start send sequence
while (buf_count) // Wait until send sequence completed
__RESET_WATCHDOG();
SPI_selectChip( false, 0); // Disable SPI slave device
for( ; ; ) {
__RESET_WATCHDOG();
}
}
//-----------------------------------------------------------------------------
// Start SPI send sequence
void SPI_send_start( byte takt)
{
if (takt == 27) pntr = data_seq1;
if (takt == 26) pntr = data_seq2;
if (takt) {
while (SPI1S_SPTEF == 0);
SPI1D = *pntr++; // Send first byte of sequence
buf_count = 31;
SPI_Interrupt( true); // Enable SPRF interrupts
}
else buf_count = 0;
}
//-----------------------------------------------------------------------------
// Interrupt functions:
__interrupt VectorNumber_Vspi1
void ISR_SPI( void)
{
(void)SPI1S; // Clear SPRF flag
(void)SPI1D;
if (buf_count) {
SPI1D = *pntr++;
buf_count--;
}
else
SPI_Interrupt( false); // Disable SPI interrupts
}
Regards,
Mac
Hi
I didn't see any problem in your code. could you provide the whole project to me? I'd like to check the PRM file and MAP file.
Best Regards
XWP