Well ok, but what does makes it incorrect?Last edited by Darrel Taylor; - 10th October 2010 at 16:56. Reason: Incorrect Mod
Well ok, but what does makes it incorrect?Last edited by Darrel Taylor; - 10th October 2010 at 16:56. Reason: Incorrect Mod
Ok, there's indeed something that relates to endpoint. I understand that you use two bytes located within the USB RAM space to get the TX and RX reports.
Now I'm clueless about what this refers to... tried to look at the hid_desc.pbp/asm code and compare it with cdc_desc.pbp/asm, and also to look on the net for RAM endpoint allocation at these two address but no luck so farBD1STATOUT = _USBMEMORYADDRESS + 8 ; 408h or 208h
BD1STATIN = _USBMEMORYADDRESS + 0Ch ; 40Ch or 20Ch
Follow up on the monologue, and after a day of digging through literature, I now have a slightly deeper understanding of the USB protocol. The more helpful was Microchip datasheet, within the USB section related to BDT RAM.
200h is start of USB RAM for PIC18F1xK50, 400h for 18Fx550/x455/x450.
I moved the allocations to Endpoint 3 for CDC usage:
Bit 7 of BDxSTAT states which device (SIE or CPU) owns the right to write or read into the dual ported USB RAM space, so this is what is used for the TX and RX ready flag.RXOWNED VAR BD3STATOUT.7 ; Out report Owned (OUT is PC to PIC)
TXOWNED VAR BD3STATIN.7 ; IN report Owned (IN is PIC to PC)
-------------------------------------------------------------------------------------------------------
BD3STATOUT = _USBMEMORYADDRESS + 18h ; 418h or 218h
BD3STATIN = _USBMEMORYADDRESS + 1Ch ; 41Ch or 21Ch
For some reason the compiler doesn't like the 3 in "BD3STATOUT and BD3STATIN" (Bad data type error). CONFIGURED_STATE should not differs between HID or CDC as it is not endpoint dependent.
Last edited by aberco; - 13th October 2010 at 22:36.
Ah thanks! that was just above, an easy fix.
RX_Ready seems to work! but TX_Ready is always true... maybe because the time when the OUT endpoint is owned by the SIE is so short that I can't see it? However if I do a loop that sends data as soon as the SIE is ready I have huge data loss.
Right now I have to add a 200ms delay between each 32Bytes packets I send in order to avoid data transmission loss. It is rather slow... reading a 24LC512 at this speed would take a bit less than 4h.
Am I missing something here?
Last edited by aberco; - 13th October 2010 at 23:28.
My shipping container just arrived yesterday with all my stuff from California, still unloading it.
Hopefully I can get some computers setup soon to be able to work on this stuff again.
Can't sit in the forum at work, just too busy during the day.
If you haven't figured it out by next week, I'll be back on it.
Sorry, I haven't been much help.
DT
No Darrel, you have been very helpful so far, at least to set me on the right course to fix issues.
I'm much more of an hardware person, getting better and better at programming but some time simple software tricks are not obvious to me... However when it comes to reading datasheets and understanding hardware peripherals, registers and configuration bits I feel at home.
I will carry on progress one step at a time
I think that most of my USB problems are solved now!
I rewrote the USB Out routine as such:
- Fist step is to calculate how many bytes are used in the string (not = 0)Code:'******************************************************* 'Writing data to USB port '******************************************************* DoUSBOut: USBBufferSizeTX = 0 FOR Counter = 1 TO USBBufferSizeMax 'Calculate number of valid bytes within the string IF USBBuffer [Counter - 1] > 0 THEN USBBufferSizeTX = USBBufferSizeTX + 1 NEXT Counter IF TX_READY THEN 'USB data can be transmitted TX_READY = 0 'Clear USB data send flag USBOUT 3, USBBuffer, USBBufferSizeTX, DoUSBOut ENDIF FOR Counter = 1 TO USBBufferSizeMax 'Clear the USB buffer after data has been sent USBBuffer [Counter - 1] = 0 NEXT Counter RETURN
- Second, sending data
- third, blanking the data buffer for next operation
I have no more garbage data in my strings, and I was able to remove the Pause without any data loss. Transmission is very fast now, with over 10kB/s (I have large conversion routines between my DoUSBOut, could even be faster without these).
Now onto other problems, especially getting all the interrupts to work together,and implementing ADC and ultra-low power routine.
What about publishing the generic code for CDC? I'll let you decide since it is actually minor modification to code you have written.
And everything collapsed!
The CDC USB routine was working well until now. It is working very well on my early prototypes, I made 3 more identical one and the PIC just stop running randomly after a few seconds up to several minutes. USB communication stops and LEDs turns off. It still respond to the INT0 interrupt though, and resume normal operation after reset... until it crashes again randomly.
I am puzzled as the hardware is strictly identical, the only difference I could spot is in the silicon revision of the PIC18LF14K50, says 0000006 on the working batch and 0000005 on the batch that crashes. I have inserted a simple blinking LED loop routine at the very beginning of my code, and it still crashes and stop blinking. Removing part of the program related to USB solve the crashing problem so I would think that there is something wrong in the USB CDC code I have modified.
Problem is that in the revision errata there is nothing linked to the USB SIE, and I am totally clueless about where to start to debug this issue. What could be wrong to have the PIC crash at a random time interval? some kind of buffer overflow?
A bit more debugging, it seems that only the USBIN side does crash.
At random the UpdateLEDStatus subroutine stop to be serviced, and the USBIN does not receive anymore data. When it crashes, RX_READY = 0, then if I send data RX_READY = 1 and just stay there, without being cleared. the USBOUT side toes work well though, even when the IN side has crashed.Code:'******************************************************* 'Reading incoming data from USB port '******************************************************* DoUSBIn: FOR counter = 1 TO USBBufferSizeMax 'Clear the USB buffer before data is received USBBuffer [counter - 1] = 0 NEXT COUNTER WHILE !RX_READY GOSUB UpdateLEDStatus WEND IF RX_READY THEN RX_READY = 0 'Clear USB data received flag USBBufferCount = USBBufferSizeRX USBIn 3, USBBuffer, USBBufferCount, DoUSBIn ENDIF RETURN
Might have something to do with USB_ASM_Service.pbp not working properly?
-> A bit more debug introducing some LED blink to see if the USB_ASM_Service is being called: it stops being called when it crashes...
Last edited by aberco; - 10th December 2011 at 20:15.
Well.. finally was able to track the problem down to a conflict between the use of SPWM_INT.bas and USB_ASM_Service.pbp. If I disable the Timer1 interrupt used for sPWM then the USB works well. Strange thing is that the code works well on 3 prototypes with the older PIC silicon revision, and does not work with 3 prototypes with the newer silicon revision...
Anyway, here is the debug program I have that run the sPWM and at the same time read a string from USB and send it back (using CDC serial port emulation).
Code:INCLUDE "cdc_desc.bas" INCLUDE "DT_INTS-18.bas" ; Base Interrupt System INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts INCLUDE "SPWM_INT.bas" INCLUDE "USB_ASM_Service.pbp" ' USB status variable handled by USBASMService ' "PLUGGED" indicates when the device is fully connected to the PC ' "RX_READY" indicates when a report has been received ' "TX_READY" indicates when it's OK to Send. The device is Plugged and the SIE is ready to accept data '******************************************************* 'Init the software multi_PWM system '******************************************************* DEFINE SPWM_FREQ 200 'SPWM Frequency DEFINE SPWM_RES 256 'SPWM Resolution DutyCycles VAR BYTE [3] 'DutyCycle Variables RedDutyCycle VAR DutyCycles [0] GreenDutyCycle VAR DutyCycles [1] BlueDutyCycle VAR DutyCycles [2] ASM SPWM_LIST macro ;Define Pin's to use for SPWM and the associated DutyCycle variables SPWM_PIN PORTC, 3, _RedDutyCycle SPWM_PIN PORTC, 6, _GreenDutyCycle SPWM_PIN PORTC, 4, _BlueDutyCycle endm SPWM_INIT SPWM_LIST ;Initialize the Pins ENDASM '******************************************************* 'Init the interrupt handling system '******************************************************* ASM ;----[High Priority Interrupts]------------------------- INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler USB_INT, _DoUSBSERVICE, ASM, yes INT_Handler TMR1_INT, SPWMhandler, ASM, yes endm INT_CREATE ; Creates the High Priority interrupt processor ENDASM '******************************************************* 'BlueTooth module initialisation '******************************************************* @ INT_ENABLE USB_INT ; Enable USB Servicing interrupt @ INT_ENABLE TMR1_INT ; Enable PWM interrupt '******************************************************* 'Main program loop '******************************************************* MainLoop: GOSUB DoUSBIn GOTO MainLoop '******************************************************* 'Reading incoming data from USB port '******************************************************* DoUSBIn: FOR counter = 1 TO USBBufferSizeMax 'Clear the USB buffer before data is received USBBuffer [counter - 1] = 0 NEXT COUNTER WHILE !RX_READY PAUSEUS 5 WEND IF RX_READY THEN RX_READY = 0 'Clear USB data received flag USBBufferCount = USBBufferSizeRX USBIn 3, USBBuffer, USBBufferCount, DoUSBIn ENDIF GOSUB DoUSBOUT RETURN '******************************************************* 'Writing data to USB port '******************************************************* DoUSBOut: USBBufferSizeTX = 0 FOR counter = 1 TO USBBufferSizeMax 'Calculate number of valid bytes within the string IF USBBuffer [counter - 1] > 0 THEN USBBufferSizeTX = USBBufferSizeTX + 1 NEXT COUNTER IF TX_READY THEN 'USB data can be transmitted TX_READY = 0 'Clear USB data send flag USBOUT 3, USBBuffer, USBBufferSizeTX, DoUSBOut ENDIF HSEROUT [STR USBBuffer \USBBufferSizeTX] ClearUSBBuffer: FOR counter = 1 TO USBBufferSizeMax 'Clear the USB buffer after data has been sent USBBuffer [counter - 1] = 0 NEXT COUNTER RETURN END
After debugging everything pinpoint an issue coming from the different revision of the PIC. The CDC routine works with silicon revision 0000006 of the PIC18LF14K50, but not 0000005.
Really getting stuck there as I have no clue of how to solve the problem, and I cannot rely on ordering a specific revision of the microcontroller...
Bookmarks