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.

TM4c123gxl UART1 FIFO Interrupt missing

Hello

I have a UART communication with a motorcontroller. Befor the FIFO i sent it with the same function but to receive i waited in a for-loop until there is a character available. This methode blocked the hole MC for a long time. 

I want to give an interrupt by 3 bytes available which means the Rx FIFO is 1/8 full. I dont need the Tx-FIFO. 

My problem now: I never get an Interrupt. If i enable the Tx-Interrupt i get one and it runs the UART1IntHandler. So its not a problem with the Implementation of the Handler itselfe. Even Send worked fine befor enable FIFO. Do I miss something in the Initialisation for the FIFO? Is it how i send? Do i need to send it with the Tx FIFO aswell?

Thank you very much

Best regards

//This are my variables i need for my Ringbuffer

typedef struct { uint8_t buffer[64]; uint8_t count_in; uint8_t count_out; uint8_t charavail; }UART_Buffer; UART_Buffer UART1_Buffer; // This is the initialisation of the UART1 with FIFO void uartInit(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); GPIOPinConfigure(GPIO_PB0_U1RX); GPIOPinConfigure(GPIO_PB1_U1TX); GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX7_8, UART_FIFO_RX1_8); IntEnable(INT_UART1); UARTEnable(UART1_BASE); UARTIntEnable(UART1_BASE, UART_INT_RX); UARTFIFOEnable(UART1_BASE); IntMasterEnable(); } // This is the Function builds the String to ask for some values from slave void uartReadRegister(uint32_t uartBase, uint16_t registerAddress) { uint16_t crc; uint8_t sendByte[8]; //uint8_t receiveByte[7]; sendByte[0] = 1; // Slave ID sendByte[1] = 0x03; // Function Code sendByte[2] = (registerAddress >> 8) & LOW_BYTE_MASK; // Start Address High Byte sendByte[3] = registerAddress & LOW_BYTE_MASK; // Start Address Low Byte sendByte[4] = 0; // Number of Registers High Byte sendByte[5] = 4; // Number of Registers Low Byte crc = getCRC(sendByte, 6); // Function to calculate CRC sendByte[6] = crc & LOW_BYTE_MASK; // CRC Low Byte sendByte[7] = (crc >> 8) & LOW_BYTE_MASK; // CRC High Byte uartSendFrame(uartBase, sendByte, 8); //uartReceiveFrame(uartBase, receiveByte, 7); //Method without FIFO // return ((receiveByte[3] << 8) + receiveByte[4]); // return value without FIFO }


// This is the function to send String(worked fine before FIFO enabled
void uartSendFrame(uint32_t uartBase, uint8_t* sendByte, uint8_t length) {
     uint8_t i;
     for (i = 0; i < length; i++) {
          UARTCharPut(uartBase, sendByte[i]);
     }
}

// UART Interrupt handler void UART1IntHandler(void) { uint32_t ui32Status; ui32Status = UARTIntStatus(UART1_BASE, true); //get interrupt status UARTIntClear(UART1_BASE, ui32Status); //clear the asserted interrupts while(UARTCharsAvail(UART1_BASE)){ UART1_Buffer.buffer[UART1_Buffer.count_in] = UARTCharGetNonBlocking(UART1_BASE); UART1_Buffer.count_in = ++UART1_Buffer.count_in & 0x3f; UART1_Buffer.charavail++; } } // This function is to analyze the string i received

void MotorControllerBufferRead(struct Motors* Motor, uint32_t uartBase, UART_Buffer Buffer){ if(Buffer.charavail >=8){ if(Buffer.buffer[Buffer.count_out+1] == 0x10){ Buffer.count_out = (Buffer.count_out + 8) & 0x3F; Buffer.charavail -= 8; } } else if(Buffer.charavail >= 13){ if(Buffer.buffer[(Buffer.count_out+1) & 0x3F] == 0x03){ Motor->speed = ((Buffer.buffer[(Buffer.count_out + 3) & 0x3F] << 8) + Buffer.buffer[(Buffer.count_out + 4) & 0x3F] ) / 60.0f; Motor->dcVoltage = ((Buffer.buffer[(Buffer.count_out + 7) & 0x3F] << 8) + Buffer.buffer[(Buffer.count_out + 8) & 0x3F] ) / 32.0f; Motor->dcCurrent = ((Buffer.buffer[(Buffer.count_out + 9) & 0x3F] << 8) + Buffer.buffer[(Buffer.count_out + 10) & 0x3F] ) / 32.0f; Buffer.count_out = (Buffer.count_out + 13) & 0x3F; Buffer.charavail -= 13; } } }

// This is the old function to receive a byte.

void uartReceiveFrame(uint32_t uartBase, uint8_t* receiveByte, uint8_t length) {
     int32_t tempByte = 0;
     uint16_t attempt = 0;
     uint8_t i = 0;

     do {
          tempByte = UARTCharGetNonBlocking(uartBase);
          if (tempByte != -1) {
               attempt = 0;
               receiveByte[i] = tempByte;
               ++i;
          } else {
               ++attempt;
               if (attempt > 5000) {
                    break;
               }
          }
     } while (i < length);
}

  • Hello Steffen

    Your code seems to be structurally correct. There are a couple of things I would need you to check

    1. Is the Register Window or Memory window in the IDE open for the UART peripheral address space?
    2. Can you enable the Receive Timeout interrupt and check the code execution?
  • Steffen,

    Unlike most (all?) other UARTs the receive timeout is a separate interrupt that must also be enabled. So if it is not enabled you will not receive an interrupt at all until you reach the FIFO trigger level. You are practically guaranteed to leave characters in the FIFO unless you also enable the receive timeout. The response to the receive timeout is identical to the receive interrupt.

    Robert
  • Hello Amit

    Thank you for your fast reply
    I enabled the Receive Timeout interrupt mask now, but the FIFO is allways empty, the emptyflag of receive and send FIFO is always 1. Is it my sending function which does not work with the FIFO?
  • Robert,
    Thank you for your reply

    i should receive more than 7 Bytes but I dont get any bytes. But i enabled the Receive Timeout now. Thanks

    Steffen
  • Amit and Robert
    Thank you very much for your help.
    Unfortunatly it was my fault. I sent two commands too quick, so the motorcontroller didn't know what to do and didn't send anything back.
    Now the FIFO gets something and works perfectly.

    regards,

    Steffen
  • There's something to be said for testing with a terminal before involving the automatic responses of another automata ;)

    Robert
  • Hello Steffen

    Even if two commands are sent quickly, a data structure should help to queue the same. And also it does not explain why receive interrupt was not getting asserted.