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.

RTOS/TM4C1290NCPDT: USB Communication through ISR

Part Number: TM4C1290NCPDT
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

Hello.  I'm trying to get a USB device to communicate through to our device.  Right now we're just looking for the device to send characters through the USB cable.  Long term we would like to have this also be a way to update our board, but right now, the goal is to get it talk properly.  Everything is up and running, it's just the communications that are not working right. I have borrowed code from the usbserialdevice_EK_TM4C129XL_TI example to get the project off the ground.  So here is my initialization of the USB and ISR

void Init_USB0(void)
{

	USBRingBufInit(&RingBuffer3, Rx3Buffer, 1024);

	Session3.pRingBuffer = &RingBuffer3;
	Session3.pfnUSBSend = &USB0_Send;
	USBCDCD_init();
	USBIntDisableControl(USB0_BASE, USB_INTCTRL_RESET |
			USB_INTCTRL_DISCONNECT |
			USB_INTCTRL_RESUME |
			USB_INTCTRL_SUSPEND |
			USB_INTCTRL_SOF);
	USBIntDisableEndpoint(USB0_BASE, USB_INTEP_ALL);
	IntDisable(INT_USB0);
	IntEnable(INT_USB0);
	USBIntEnableEndpoint(USB0_BASE, USB_EP_1);

	USBIntRegister(USB0_BASE, USB0_ISR);
}

USBCDCD_init() goes to the example code and nothing is changed there.  I disabled the controller and endpoint interrupts because I only need the interrupt when something is coming over the line.

void USB0_ISR(void)
{
	uint32_t ui32Status;

	ui32Status = USBEndpointStatus(USB0_BASE, USB_EP_1);

	if (ui32Status == USB_DEV_TX_TXPKTRDY)
	{
		USBRingBufWriteOne(&RingBuffer3, USBEndpointDataGet(USB0_BASE, USB_EP_1, read_data, data_size));

	}
	USBDevEndpointDataAck(USB0_BASE,USB_EP_1,true);
	USBDevEndpointStatusClear(USB0_BASE, USB_EP_1, ui32Status);
	USB0DeviceIntHandler();

}

The ring buffer by the way is where we process all our bytes.  It's how existing code already is written and will be easiest to conform to that method.  Here is the declaration of read_data and data_size

uint8_t read_data[1024];
uint32_t *data_size;

Finally my send part of the code:

void USB0_Send(const uint8_t *pui8Buffer, uint32_t ui32Count)
{
	unsigned int buffAvailSize;
	while(ui32Count--)
	{
		buffAvailSize = USBBufferSpaceAvailable(&txBuff);
		while(buffAvailSize == 0){
			buffAvailSize = USBBufferSpaceAvailable(&txBuff);
			Task_sleep(10);
		}
		USBBufferWrite(&txBuff, (uint8_t *)*pui8Buffer++, 1);
	}

}

Currently my code is not even getting to this point, so I haven't worked on making this part any better.  Please let me know if there is something else I've forgotten to mention.  

  • Also, ui32Status when non-zero is x00000004.
  • Hello Stephen,

    First off as an FYI I edited your post to make the code blocks clearer. This is done by using the Syntax Highligher feature when posting (for replies, you need to click 'Use rich formatting' to access). It's the symbol that has '< >'.

    You said you looked at the usbserialdevice_EK_TM4C1294XL_TI_TivaTM4C1294NCPDT example to borrow code from it, but it's not clear what your starting base was, what worked beforehand, etc. - can you instead port the TI example to your MCU and then modify it once you get that working? That would be the far simpler way to handle this. If you need to make any modifications, it would only need to be potentially pinout mods.

    I'm not terribly familiar with the TI-RTOS USB example and what you posted diverges from it heavily... hard to say where you may have gone wrong with the information provided.

    Also just as a general note since you didn't mention it... are you making sure the USB hardware is initialized with either Board_initUSB or EK_TM4C1294XL_initUSB?
  • Hi Ralph,

    Just to make sure I understand you correctly, you'd like me to try to modify the usbserialdevice_EK_TM4C1294XL_TI code for what I'm attempting to do and see where it doesn't work? When I use the example code, it works right out of the box for me, no modification or anything. The code I've got here is original for our current board needs.

    Thanks for the last point of clarification. I have made sure that the board works and works properly. Originally, before I started with my modifications made sure the message "TI-RTOS controls USB." came through the device to make sure it was properly initialized.

    Also, when I look at the register while looping through my USB0_ISR, I noted in FIFO1 the bytes I'm looking for, so basically I see them, I just can't figure out how to grab them!

    Finally, thank you for editing my post for ease of reading. It looks WAY better.

  • Hi Stephen,

    If the example is working, I would recommend porting as much of it over as possible.

    I am not seeing much correlation between your example and the TI-RTOS example. For example I don't see any Ring Buffers or USBEndpoint API's.

    I would recommend keeping the porting process simple to start with. Even if those steps are your ultimate goal, first integrate the relevant portions of the RTOS project to your current project. Once that works, then work on adding/changing the functionality one step at a time so if something breaks you can know exactly where in the process it went wrong.

    As far as reading data goes, usually the USBBufferRead API is needed for that. I don't see anything like that or even akin to it in your posted code. Take a look at the USBCDCD_receiveData function including the rxData API.
  • Hi Ralph,

    Thank you for your help so far.  So I went back to the initialization of the USB device.  

    void Init_USB0(void)
    {
        Task_Params taskParams;
        USBRingBufInit(&RingBuffer3, Rx3Buffer, 4096);
        Session3.pRingBuffer = &RingBuffer3;
        Session3.pfnUSBSend = &USB0_Send;
        USBCDCD_init();
        Task_Params_init(&taskParams);
        taskParams.stackSize = TASKSTACKSIZE;
        taskParams.stack = &task0Stack;
        taskParams.priority = 1;
        Task_construct(&task0Struct, (Task_FuncPtr)transmitFxn, &taskParams, NULL);
    
        taskParams.stack = &task1Stack;
        Task_construct(&task1Struct, (Task_FuncPtr)receiveFxn, &taskParams, NULL);
    }

    With similar to the example for code:

    oid receiveFxn(UArg arg0, UArg arg1)//This Section needs to go into ISR
    {
        unsigned int received;
        while (true) {
            /* Block while the device is NOT connected to the USB */
            USBCDCD_waitForConnect(BIOS_WAIT_FOREVER);
            received = USBCDCD_receiveData(readBuffData, 1, BIOS_WAIT_FOREVER);
            USBRingBufWriteOne(&RingBuffer3, readBuffData[0]);
        }
    }
    Void transmitFxn(UArg arg0, UArg arg1)//This Section needs to go into Send
    {
        while (true) {
    
            /* Block while the device is NOT connected to the USB */
            USBCDCD_waitForConnect(BIOS_WAIT_FOREVER);
    
            USBCDCD_sendData(text, sizeof(text), BIOS_WAIT_FOREVER);
    //        GPIO_toggle(Board_LED0);
    
            /* Send data periodically */
            Task_sleep(2000);
        }
    }

    This has been functioning for me properly as we would expect.  My problem is coming when I attempt to put this, instead of initializing it at the beginning, into my ISR.  I get this error:

    ti.sysbios.knl.Task: line 635: assertion failure: A_badThreadType: Cannot create/delete a task from Hwi or Swi thread.

    void USB0_ISR(void)
    {
    Task_Params taskParams;
    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    taskParams.priority = 1;
    Task_construct(&task0Struct, (Task_FuncPtr)transmitFxn, &taskParams, NULL);
    
    taskParams.stack = &task1Stack;
    Task_construct(&task1Struct, (Task_FuncPtr)receiveFxn, &taskParams, NULL);
    
    USB0DeviceIntHandler();
    
    }
    
    

  • Hello Stephen,

    That is because you cannot use a task_construct call inside of an HWI/SWI.

    Please see the "Calling Context" table in the following link for reference of what you can/can't do within your ISR and then modify your code based on this: software-dl.ti.com/.../Event.html
  • Thank you for all of your help Ralph. I now have it running and working for the most part.  Now it's just how the two are talking to each other.  Thanks again.