Hi All,
Using MC9S08JM60 chip and DEMOJM Kit, I wrote a software in C# similar to the Freescale GUI for USB application Training, which can be found in the following link:
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=USBJM_TRAINING&nodeId=01624684491437
In the microcontroller code I used the firmware example in the above link and wrote my functions for the keyboards in it.
Now the problem is when I use an external power supply and disconnect the USB cable, the keys are not functioning at all as there are when the USB cable is connected. I have found out that the function in main.c called Check_USBBus_Status() is causing this issue. I don't exactly know how this function helps the keyboards interrupt to fail. When I remove the function, the USB port won't work even when the connection exists.
It is so appreciated if someone let me know how I am going to fix this problem.
Thanks alot,
Red
Solved! Go to Solution.
Hi Tsuneo,
Thank you so much for thehelpful information and sorry about the delay in reply back to your message.
When you said the problem was Check_USBBus_Status() function I used a trick to bypass it in main.c in the absence of VBUS. Something like:
//
if(PTGD_PTGD3) {
USBATTACHED = TRUE;
}
//
and in for( ; loop:
//
if(USBATTACHED)
{
Check_USBBus_Status();
}
//
This was a quick fix for the problem and painful for the user to change the mode at Reset . I got what you said about the VBUS assignment to (any) input ports, but because I already made my PCB for the device I am making with S08JM60, I have to modify it to make the self power detection happens.
Again I truly appreciate your respond to my info. request.
Best Regards
Red
Now the problem is when I use an external power supply and disconnect the USB cable, the keys are not functioning at all as there are when the USB cable is connected. I have found out that the function in main.c called Check_USBBus_Status() is causing this issue.
Sound like the device drops in Suspend. USB_Suspend() is called from Check_USBBus_Status().
As your device is a self-powered one, enable SELF_POEWER by adding this macro to Usb_Config.h
Usb_Config.h#define SELF_POEWER
And then, Check_USBBus_Status() disable the USB engine (SIE) when the device is disconnected, by seeing VBUS voltage at the port.
Once the engine is disabled, Suspend event doesn't occur, too.
But to make it sure, comment USB_Suspend() call in Check_USBBus_Status()
void Check_USBBus_Status(void){ ... ... if(Usb_Device_State == USB_ENTER_SUSPEND) {// USB_Suspend(); <----------- comment this line }}Your main loop task works just when USB connection is established.
It doesn't need to run while disconnected.
For such tasks, enclose them with "if (Usb_Device_State == CONFIGURED_STATE){ }", as follows.
/* Main Loop */for(;;) { /* USB Manager, please keep it in main Loop */ Check_USBBus_Status(); if (Usb_Device_State == CONFIGURED_STATE) // run this contents just when USB connection is established { if (ButtonPressed) { // If there is any change in the switches, send the status EP2_Buffer[0] = SWITCHES_PORT; //assign value of the push buttons to EP2 buffer EndPoint_IN(EP2,8); //send data ButtonPressed = 0; //clear ButtonPressed flag KBI_ENABLE(); //enable KBI } else if(CheckEndPointOUT(EP1)) { // If data was received in EP1, set LEDs value LED0 = ~(EP1_Buffer[0]); LED1 = ~(EP1_Buffer[0] >> 1); LED2 = ~(EP1_Buffer[0] >> 2); LED3 = ~(EP1_Buffer[0] >> 3); } else if (CheckEndPointOUT(EP3)) { //check first byte (command) if (EP3_Buffer[0] == WRITE_LEDS) { //Change LEDs value LED4 = ~(EP3_Buffer[1] >> 4); LED5 = ~(EP3_Buffer[1] >> 5); LED6 = ~(EP3_Buffer[1] >> 6); LED7 = ~(EP3_Buffer[1] >> 7); } else if (EP3_Buffer[0] == READ_ANALOG_DATA) { //Read analog data and send it through EP4 EP4_Buffer[0] = READ_POT(); EP4_Buffer[1] = READ_ACCEL_X(); EP4_Buffer[2] = READ_ACCEL_Y(); EP4_Buffer[3] = READ_ACCEL_Z(); EP4_Buffer[4] = SWITCHES_PORT; EndPoint_IN(EP4,8); } } }}Tsuneo
Hi Tsuneo;
Thank you very much for the respond. I have modified the code by putting " if(Usb_Device_State == CONFIGURED_STATE) in the main and commented the USB_Suspend() method out of the code. What I did not do is difining micro for the SELFPOWER mode. It is already defined in the Usb_Config.h.
My point is if I use IF statement in the main.c as you mentioned, I am practically disabling the method that manipulate my keyboard commands in no USB connection state. So it won't work if Usb_Device_State == CONFIGURED_STATE, is that right or I am missing something big here?!.
Modification Result: So after the modifications, in no USB connection state, the keys are still disabled. So it is not USB_Suspend() that causing the problem I guess.
Thank you so much.
Red
What I did not do is difining micro for the SELFPOWER mode. It is already defined in the Usb_Config.h.
If SELF_POEWER is already enabled, but if you still see the device drops in Suspend, Port G D0 is not connected to VBUS pin of USB connector on the board. Check the Port G D0 connection. This port is examined by Check_USBBus_Status() for VBUS detection when SELF_POEWER is enabled.
I don't know if this port is connected to the USB connector on your board.
For the pair of DEMOJM mother board and JM60 daughter card, Port G D0 is connected to push button over J27 Jumper. For self-powered setting, I took off the J27 jumper and connected it to J12 (VBUS_SEL) pin2 externally, with a protection resistor and another weak pull-down resistor, and a small bypass capacitor. In this way, VBUS detection on the code works on this board.
My point is if I use IF statement in the main.c as you mentioned, I am practically disabling the method that manipulate my keyboard commands in no USB connection state. So it won't work if Usb_Device_State == CONFIGURED_STATE, is that right or I am missing something big here?!.
Place the key scan task out of the "if" clause, and enclose just the USB endpoint operations in the "if" clause.
Tsuneo
Thank you very much for the respond. I just want to confirm whether VBUS is Vusb33 (pin25) on the chip?.
By the way I am using PTG0 to execute a function in my code. If I connect it to VBUS, It will conflict with the voltage on the pin and my push button won't work any more.
Thank you.
Red
I just want to confirm whether VBUS is Vusb33 (pin25) on the chip?.
No.
Vusb33 pin on the JM60 is different from VBUS pin on the USB connector.
Vusb33 is an output (power) pin for the on-chip 3.3V regulator, to attach bypass capacitor.
As you need to detect plug-in at the USB connector, VBUS (5V) pin on the connector shows it.
By the way I am using PTG0 to execute a function in my code. If I connect it to VBUS, It will conflict with the voltage on the pin and my push button won't work any more.
Then, assign another port to VBUS detection.
Any port will do, if it is set up to input (default after power up).
After connecting another port on JM60 to VBUS pin on the connector, modify PTGD_PTGD0 to the port on Usb_Drv.c
Usb_Drv.cvoid Check_USBBus_Status(void){ #ifdef SELF_POWER if(PTGD_PTGD0 == USB_BUS_ATTACHED) /* Is JM60 attached on USB bus? */ { #endif
PTGD_PTGD0 appears just here in the entire source code.
Tsuneo
Hi Tsuneo,
Thank you so much for thehelpful information and sorry about the delay in reply back to your message.
When you said the problem was Check_USBBus_Status() function I used a trick to bypass it in main.c in the absence of VBUS. Something like:
//
if(PTGD_PTGD3) {
USBATTACHED = TRUE;
}
//
and in for( ; loop:
//
if(USBATTACHED)
{
Check_USBBus_Status();
}
//
This was a quick fix for the problem and painful for the user to change the mode at Reset . I got what you said about the VBUS assignment to (any) input ports, but because I already made my PCB for the device I am making with S08JM60, I have to modify it to make the self power detection happens.
Again I truly appreciate your respond to my info. request.
Best Regards
Red
When you said the problem was Check_USBBus_Status() function I used a trick to bypass it in main.c in the absence of VBUS. Something like:
//
if(PTGD_PTGD3) {
USBATTACHED = TRUE;
}//
and in for( ; ; ) loop:
//
if(USBATTACHED)
{
Check_USBBus_Status();
}//
This was a quick fix for the problem and painful for the user to change the mode at Reset .
It means that your board always enables USB engine, D+ pull-up resistor and USB interrupt.
Hi Tsuneo,
Sorry about bothering you again. It seems like I need to know much more about USB configurations than I know know.
I took the Check_USBBus_Status(); out of the if condition in the main.c for loop and commented the USB_Suspend() in Check_USBBus_Status(void) as you previously said to do. I also defined another input port to check the VBUS and called it USB_PWR.
so in Usb_Drv.c I have:
void Check_USBBus_Status(void)
{
#ifdef SELF_POWER
if(USB_PWR == USB_BUS_ATTACHED) /* Is JM60 attached on USB bus? */
{
#endif
if(CTL_USBEN == 0) /* JM60 module off ? */
{
EPCTL0 = 0x0D;
INTSTAT = 0xBF;
CTL = 0x00;
INTENB = 0x00; /* disable USB interrupt*/
CTL_USBEN = 0x01; /* enable module */
USBCTL0 = UCFG_VAL; /* attach JM60 to USB bus*/
Usb_Device_State = ATTACHED_STATE;
}
#ifdef SELF_POEWER
}
else
{
if(CTL_USBEN == 1) /* JM60 USB on ?*/
{
CTL = 0x00; /* disable module */
INTENB = 0x00; /* mask USB interrupt*/
Usb_Device_State = POWERED_STATE;
}
}
#endif
if(Usb_Device_State == ATTACHED_STATE)
{
INTSTAT = 0xBF; /*clear USB interrupts*/
INTENB = 0xBF;
}
if(Usb_Device_State == USB_ENTER_SUSPEND)
{
// USB_Suspend();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
and in main.c for loop I have:
for(;
{
/* USB Manager, please keep it in main Loop */
Check_USBBus_Status();
if (ButtonPressed)
{
// Data sent to UI in EP2
// MASEG_proc(SWITCHES_PORT);
EP2_Buffer[0] = MASEG_proc(SWITCHES_PORT);
EndPoint_IN(EP2,8); //send data
ButtonPressed = CLEAR; //clear ButtonPressed flag
KBI_ENABLE(); //enable KBI
}
}
And as I mentioned before I am using "ButtonPressed" event to check my keyboard pressing events, so I cannot use if condition like:
if (Usb_Device_State == CONFIGURED_STATE) // run this contents just when USB connection is established
{ if (ButtonPressed) { // If there is any change in the switches, send the status EP2_Buffer[0] = SWITCHES_PORT; //assign value of the push buttons to EP2 buffer EndPoint_IN(EP2,8); //send data ButtonPressed = 0; //clear ButtonPressed flag KBI_ENABLE(); //enable KBI } }
And the keyboard is not working in Self_Powered mode(using external Voltage), if I don't do the following in the main.c:
if(USB_PWR) {
USBATTACHED = TRUE;
}
//
if(USBATTACHED)
{
Check_USBBus_Status();
}
//
If you need more information please let me know and thank you so much for your time and attention.
Regards,
Red
As I told on my above post, enclose just the endpoint operation in the "if (Usb_Device_State == CONFIGURED_STATE)" clause.
if (ButtonPressed){ // If there is any change in the switches, // send the status EP2_Buffer[0] = SWITCHES_PORT; // Assign value of the push buttons to EP2 buffer if (Usb_Device_State == CONFIGURED_STATE) // Run this contents { // just when USB connection is established EndPoint_IN(EP2,8); // Send data } ButtonPressed = 0; // Clear ButtonPressed flag KBI_ENABLE(); // Enable KBI}
Tsuneo
Hi Tsuneo,
Thank you very much for the respond. I decided to attach all the related files from my project for you to see, because whatever you told me I did but the keyboard still won't work in Self_Powered Condition unless I use the if condition in main.c for the Check_USBBus_Status(); , which you said is not a good idea to do that.
The attached files might give you a better picture of the project, so you might be able to tell me what might be done to fix the problem in a safe manner.
Thank you so much for your time on that.
Regards
Red