This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SPI communication routine interruptions

Other Parts Discussed in Thread: EK-TM4C123GXL

Greetings, once again, i come up with a possible solution for the communication between 2 TM4C123GXL launchboard, bu for now i haven't been able to make routines execute. I suppose its because im using a Timer interrupt to execute a button interrupt, so the interrups are somehow causing troubles i guess.

My master have this code:


#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
#include "inc/hw_nvic.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/pwm.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include "driverlib/buttons.h"
#include "driverlib/adc.h"
#include "driverlib/timer.h"
#include "math.h"
#include "driverlib/ssi.h"

//*****************************************************************************
#define NUM_SSI_DATA 10

volatile unsigned long g_ulSSI2RXTO = 0;
uint32_t g_DataRx2[NUM_SSI_DATA];
uint32_t g_DataTx2[NUM_SSI_DATA];
uint32_t ulDataRx2[NUM_SSI_DATA];
uint32_t ulDataTx2[NUM_SSI_DATA];
unsigned long ulStatus, g_Index, ulPeriod, ulindex;
int mode;


extern void IntGPIOB(void);
void Timer1IntHandler(void);

void Init (void){

ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

// Desbloquear portas F do NMI

/*HWREG (GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG (GPIO_PORTF_BASE + GPIO_O_CR) |= GPIO_PIN_0;
HWREG (GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_M;*/

GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 |GPIO_PIN_3);
}

void InitUart (void) {

// UART Initialization
ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioConfig(0, 115200, 80000000);

}

void InitTimer (void) {

ulPeriod = (ROM_SysCtlClockGet()/100) ;
ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ulPeriod -1);

// Enable interruption Timer 1
IntEnable(INT_TIMER1A);
ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerEnable(TIMER1_BASE, TIMER_A);
ROM_IntMasterEnable();
}

void InitButtonInt (void){


GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_5);
GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_5,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5,GPIO_PIN_5);
GPIOIntDisable(GPIO_PORTB_BASE, GPIO_INT_PIN_5);
GPIOIntTypeSet(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_FALLING_EDGE);
GPIOIntClear(GPIO_PORTB_BASE, GPIO_INT_PIN_5);
GPIOIntRegister(GPIO_PORTB_BASE,IntGPIOB);
GPIOIntEnable(GPIO_PORTB_BASE, GPIO_PIN_5);
ROM_IntMasterEnable();

}

void InitSPI2(void)
{

SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);
GPIOPinConfigure(GPIO_PB4_SSI2CLK);
//GPIOPinConfigure(GPIO_PB5_SSI2FSS);
GPIOPinConfigure(GPIO_PB6_SSI2RX);
GPIOPinConfigure(GPIO_PB7_SSI2TX);

GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7);
SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 115200, 10);
SSIEnable(SSI2_BASE);
}

int main(void)
{
//volatile int ulLoop;

Init();

InitUart();

InitButtonInt();

InitTimer();

InitSPI2();


while(1)
{

//_____________________Main Cycle___________________________

}
}

void IntGPIOB(void)
{

GPIOIntClear(GPIO_PORTB_BASE, GPIO_PIN_5);
UARTprintf("IF MODE\n ");
if (mode==0){

ulDataTx2[0] = 100;
ulDataTx2[1] = 200;
ulDataTx2[2] = 300;
ulDataTx2[3] = 400;
ulDataTx2[4] = 500;
ulDataTx2[5] = 600;
ulDataTx2[6] = 700;
ulDataTx2[7] = 800;
ulDataTx2[8] = 900;
ulDataTx2[9] = 1000;


while(SSIDataPutNonBlocking(SSI2_BASE, ulDataTx2[0]))
{
UARTprintf("SSIDataPutNonBlocking\n ");
}
UARTprintf("Enviado:\n ");

for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++)
{
SSIDataPut(SSI2_BASE, ulDataTx2[ulindex]);
UARTprintf("%4d ", ulDataTx2[ulindex]);
}

while(SSIBusy(SSI2_BASE))
{
}
mode++;
GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5,GPIO_PIN_5);

}
else {

UARTprintf("Recebido:\n ");

for(ulindex = 0; ulindex < NUM_SSI_DATA; ulindex++)
{

SSIDataGet(SSI2_BASE, &ulDataRx2[ulindex]);
UARTprintf("%4d ", ulDataRx2[ulindex]);
}

while(SSIBusy(SSI2_BASE))
{
}

mode=0;
GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5,GPIO_PIN_5);
}
}
//count++;
//UARTprintf("Count = %4d \n", count);


void Timer0IntHandler(void)
{

TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

}


void Timer1IntHandler(void)
{
GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5,0);
//rpm=count*60/cog;
//count=0;
//UARTprintf("Timerinterrupt = %4d \n", count);
TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
}

I think its quite clear what im trying to do. I have checked the startup code also, and everything is in order.Somehow the timer1 its now executing but doesn't trigger the button interrupt, not detecting the FALLING_EDGE. Can you guys come up with a solution?

  • Hi,

    No, it is not clear what you really want - and the names given to functions are confusing - for instance that one with "Button" - while at first read seems to have a real mechanical "button", in fact it is not - is just a simple pin input. Keep in mind such practice does not deserve anyone, neither you, neither the forum helpers.

    The second problem is you think it is possible to change internally(from software) the state of an input pin - this is not possible with ARM architecture - once the pin is declared "input", only external events can change its state - so trying to do it fro timer interrupt is useless.

    If you plan to use it with a real mechanical switch, then again your routines are not ready to read the correct state - seems you ignore the "debouncing" - the drivers/button.c file has two routines to be used but with care (i.e. ButtonsPoll must be called from a timer interrupt - best solution). The google search will reveal you a lot of good references about debouncing.

    Not really clear the "two boards communications" - if by SPI or something else. If this is your goal, then suggest to search ARM for "interprocessor communication" - there are some doing this, but with the dedicated hardware help (maybe an idea from there).

    Petrei

  • Yes, the button must be changed to output so i can use it to control slave. but its possible to call a button interrupt from a timer, because i've done it. If it works properly thats the question.

    I've been trying to communicate for far to long with SPI, i think im going to change it for UART.

  • Hi, 

    Look in Tiva/examples/boards/ek-tm4c123gxl/qs-rgb/ application and you will see a good example how to use the buttons. My advise is to use this and never think about edge triggerd interrupt with mechanical switch/button.

    As for communicating with another micro using SPI maybe you tried the master-slave combination but in this case, the slave must run at a system clock not bigger than master's/12. Other alternatives are of coarse UART or CAN, depend also on distance....

    Petrei