Quantcast
Channel: Microcontrollers
Viewing all articles
Browse latest Browse all 239555

Forum Post: SCI RX Interrupt issues -- previously working code no longer functions

$
0
0
Hi, I have a rather odd situation. I'm working on getting comms between a PC and a F28377D using the SCI, and a while ago built a quick test bench just to ensure that the MCU could send and receive values in an interrupt driven manner. The idea was to just regularly push incremented characters (A through Z) and upon receipt of a character send "You sent: " with the received character. This was working, and I moved on to more advanced behavior. However, the RX interrupt (and in fact most of the entire RX FIFO) has ceased to operate correctly -- upon starting, the RX interrupt will fire twice in rapid succession, and then no more. The register indicates anywhere from 0 to 3 characters in the FIFO (seems not to be deterministic), but the value "received" is always 0h. If I send data to the MCU, I can see the RX LED blinking with each keypress, but the interrupt never fires and checking the RX register shows no data (again just 0h). Here's the odd thing: I branched from a previous commit (the basic testbench) in Git to verify I understood how everything was working, and it no longer works . I see the same firing of the RX interrupt twice and then no more, and no data being received in the FIFO. Nothing in the old code has changed. This been tested across 2 separate boards in both Windows 10 and Linux Mint, and with several USB cables, and the behavior is the same across all configurations. I am using PuTTY on both platforms. Code for the basic testbench is as follows (warts and all): #include "F28x_Project.h" // Device Headerfile and Examples Include File #include "77D_sci.h" // Device specific SCI functions #define CPU_FREQ 60E6 #define LSPCLK_FREQ CPU_FREQ/4 #define SCI_FREQ 100E3 #define SCI_PRD (LSPCLK_FREQ/(SCI_FREQ*8))-1 // Prototype statements for functions found within this file. interrupt void sciaTxFifoIsr(void); interrupt void sciaRxFifoIsr(void); __interrupt void cpu_timer0_isr(void); void scia_fifo_init(void); void error(void); //void scia_xmit(int a); //void scia_msg(char * msg); // Global variables Uint16 ReceivedChar; // Used for checking the received data int RXRCV_flag = 0; int TXRDY_flag = 0; void main(void) { // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the F2837xD_SysCtrl.c file. InitSysCtrl(); // Step 2. Initialize GPIO: // This example function is found in the F2837xD_Gpio.c file and // illustrates how to set the GPIO to it's default state. InitGpio(); // Init the pins for the SCI-A port. // GPIO_SetupPinMux() - Sets the GPxMUX1/2 and GPyMUX1/2 register bits // GPIO_SetupPinOptions() - Sets the direction and configuration of the GPIOS // These functions are found in the F2837xD_Gpio.c file. GPIO_SetupPinMux(28, GPIO_MUX_CPU1, 1); GPIO_SetupPinOptions(28, GPIO_INPUT, GPIO_PUSHPULL); GPIO_SetupPinMux(29, GPIO_MUX_CPU1, 1); GPIO_SetupPinOptions(29, GPIO_OUTPUT, GPIO_ASYNC); // Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interrupts DINT; // Initialize PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared. // This function is found in the F2837xD_PieCtrl.c file. InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000; // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in F2837xD_DefaultIsr.c. // This function is found in F2837xD_PieVect.c. InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.SCIA_RX_INT = &sciaRxFifoIsr; PieVectTable.SCIA_TX_INT = &sciaTxFifoIsr; PieVectTable.TIMER0_INT = &cpu_timer0_isr;//assign ISR's, add more if needed EDIS; // This is needed to disable write to EALLOW protected registers //Initialize and Configure the timers InitCpuTimers(); ConfigCpuTimer(&CpuTimer0, 200, 400000); //initial configuration CpuTimer0Regs.TCR.all = 0x4000; //write only instruction to set TSS bit = 0 PieCtrlRegs.PIEIER1.bit.INTx7 = 1; DINT; // Step 4. Initialize the Device Peripherals: scia_fifo_init(); // Init SCI-A // Step 5. User specific code, enable interrupts: //ReceivedChar = sdataA[0]; // Enable interrupts required for this example PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block PieCtrlRegs.PIEIER9.bit.INTx1=1; // PIE Group 9, INT1; corresponds to SCIA_RX PieCtrlRegs.PIEIER9.bit.INTx2=1; // PIE Group 9, INT2; corresponds to SCIA_TX PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable TINT0 in the PIE, group 1 interrupt 7 //IER = 0x101; // Enable CPU INT IER |= 0x0101; //enable cpu int1 which is connected to cpu timer 0 EINT; // Step 6. IDLE loop. Just sit and loop forever (optional): for(;;); } And the ISR's are as follows: interrupt void sciaTxFifoIsr(void) { if(RXRCV_flag == 1){ scia_msg("You sent: \0"); scia_xmit(ReceivedChar); scia_msg("\r\n\0"); RXRCV_flag = 0; PieCtrlRegs.PIEACK.all|=PIEACK_GROUP9; // Issue PIE ACK } else{ TXRDY_flag = 1; } SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag PieCtrlRegs.PIEACK.all|=PIEACK_GROUP9; // Issue PIE ACK } interrupt void sciaRxFifoIsr(void) { ReceivedChar = 0; ReceivedChar = SciaRegs.SCIRXBUF.bit.SAR; // Read data //ReceivedChar = SciaRegs.SCIRXBUF.all; RXRCV_flag = 1; SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear Overflow flag SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag PieCtrlRegs.PIEACK.all|=PIEACK_GROUP9; // Issue PIE ack } __interrupt void cpu_timer0_isr(void){ CpuTimer0.InterruptCount++; static Uint16 count = 0x41; //effectively "A" if(TXRDY_flag == 1){ scia_xmit(count); scia_msg("\r\n\0"); TXRDY_flag = 0; if(count >= 0x5A){ count = 0x41; } else{ count++; } } // Acknowledge this interrupt to receive more interrupts from group 1 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } My FIFO declaration function is as follows: void scia_fifo_init() { SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback // No parity,8 char bits, // async mode, idle-line protocol SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK, // Disable RX ERR, SLEEP, TXWAKE SciaRegs.SCICTL1.bit.RXERRINTENA = 1; // Enable RX interrupts SciaRegs.SCICTL2.bit.TXINTENA =1; //SCITXBUF interrupt enable SciaRegs.SCICTL2.bit.RXBKINTENA =1; //Receiver-buffer/break interrupt enable /* * Baud rate is determined as follows: * BRR = (SCIHBAUD << 8) && SCILBAUD * Baud = LSPCLK / ((BRR+1)*8) * LSPCLK should be 50MHz by default (200MHz/4) * If BRR == 0, then Baud = LSPCLK/16 (or 3,125,000 by default) */ SciaRegs.SCIHBAUD.all = 0x0002; SciaRegs.SCILBAUD.all = 0x008B; //SciaRegs.SCIHBAUD.all = 0x0000; //SciaRegs.SCILBAUD.all = 0x0000; SciaRegs.SCICCR.bit.LOOPBKENA = 0; // disable loop back SciaRegs.SCIFFTX.all=0xC022; //enable+rst fifo, sets TX FIFO interrupt level to 2, enables TX interrupt SciaRegs.SCIFFRX.all=0x0021; //set RX FIFO interrupt level to 1, enables RX interrupt SciaRegs.SCIFFCT.all=0x00; SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset SciaRegs.SCIFFTX.bit.TXFIFORESET=1; SciaRegs.SCIFFRX.bit.RXFIFORESET=1; } The entire repo is hosted here: https://github.com/silk2390/sci_testbench_alt I'm currently working at the "Actual portability testing and baud update" commit, and the only change I made was to set the baud rate to 9600 instead of the 3.125M it was at (I suspected the high rate may have been the issue). Please let me know if I can do anything to clarify.

Viewing all articles
Browse latest Browse all 239555

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>