Edit Translation
by Transposh - translation plugin for wordpress
IPv6 logo

VUSiBino demo – Parte I – the Firmware

Before proceeding with circuits and “shields for VUSiBino, we'll explain a little about how the program we've charged as an example and work program “host” to control the microcontroller. Its basic function is to demonstrate how we can change the status of the pins, send and receive information from the PC to the device. My knowledge of C and C ++ are, to put it mildly very limited, the code is somewhat flustered, but it works. Currently only runs on Windows due to not being able to compile cross-platform libraries. Thank Joonas Pihlajamaa of Code And Life its excellent programming guide v-USB, without which I do not think I would have been able to occur to me this.

*Note of the 10 of dieicembre of 2017, It corrected the code where sw_led was assigned incorrectly.

the Firmware.

To develop and compile the firmware I used AVR Studio 5, he “toolchain” winAVR, the libraries v-usb. To upload the device, AVRdudess.

Once installed AVR Studio 5 and WINAVR simply open the file in the directory vusibino.avrgccproj Firmware.

Usbconfig.h file in the directory usbdrv configure the behavior of VUSiBino, the current that is fed (Default is 50mA), we change it to 100mA.

Below we define the device identification strings, If you do not have IDs, Obdev allows us to use their identifiers whenever we comply with the rules outlined in the document readme.txt, deputy in the directory usbdrv.

We can now define manufacturer name and device, and a serial number. Useful for distinguishing our device we are using another with the same identifier provided by Obdev.

If you also plan to use several of our devices, This definition allows us to change the serial number dynamically if necessary. With this we would set up the USB to be identified and properly communicate with the PC. You can set many other variables, and even define a HID device, that does not require drivers, but it is not the purpose of this device.

Then the file had “vusibino.c”, which it is where we schedule events that respond VUSiBino. In this example we will focus on communication with the host. We begin by defining the MCU clock speed, If that is not defined in the makefile or IDE. After that we define the length of the serial number, which must be equal to that defined in the file “usbconfig.h”. We create a global variable to handle the serial number and we define the labels we use to manage commands that you send us the control program, for convenience these labels will be defined the same way in the host code. And we end by defining global variables for the data received and sent. They are not very recomendades C, but they save a lot of work in programming the MCU to non-experts like me.

We passed handling routines serial number. “usbFunctionDescriptor” we will return the serial number defined by “serialNumberDescriptor” and modify to our liking using “SetSerial”. In other words, to change the serial n'ñumero us simply call Setserial(serialNum); and we work with serialNum to handle this data before passing it to the controller.

The following is managing information sent to us the host, using the function “usbFunctionSetup” and deciding what to do in each case. The global variable operation the we zero to avoid confusion later. The sw_led variable is used to find out what state LED, if the second bit is zero, It will behave statically. We ensure this by applying a bit mask operator “and”, each bit of the tag is compared with bit mask, if both are one, the result is a one, if any it is not, will be zero. The mask is all ones, except the bit you want to change. With the variable “sw_led” we will use other operation, “and”, more appropriate to put the bits we want to zero. If a bit is one, and the other also, the result is one, otherwise at position zero is stored. As we reset the second bit of the variable, all bits of the comparator will be one except that.

The table below is a “truth table” showing the results of operations “and” and “or”.

A&B 1 0 A|B 1 0
1 1 0 1 1 1
0 0 0 0 1 0

Explain cases:

The switch order evualuará the data sent by the host and stored in the variable “rq-bRequest” V-USB.

-Caso USB_LED_BLINK. If the host sends the command “USB_LED_BLINK”, the second routine will sw_led one bit using a “bitmask” with the operation or. each bit with a one or a zero is compared, if the bit of the variable is zero and the comparator tmbién, It is saved zero, if any of them is a One, It will be stored a one in that position. As we do not tell him to get out of the routine or sequence of questions (swith case), the program will continue with the next instruction. We do to take advantage of the code following case, LED Lighting.

-Caso USB_LED_ON. Change the second bit “sw_led” to zero “and”. The program will go through here after having gone through “USB_LED_BLINK” or if the host has sent “USB_LED_ON”. It is where the LED lights change the status pin13 (PB5), that is where we have the red LED, to be output in the AVR port DDRB applying a mask. To turn the LED, We activate the pin13 with the same technique. And we left the function “return 0” not to prosecute the following instructions.

-Caso USB_LED_OFF. Change the second bit “sw_led” to zero “and”. Previemente turned the ignition pin with another logical operation using a macro that defines the pin in bookstores AVR, “PB5” It refers to the five pin port B, which corresponds to the pin 13 Arduino and VUSiBino. The operation is to put a bit on PB5, and compare it with the current state, and deny it if it is a one, then we will function.

This is an example of the most common notation for these operations will see in the examples we find in the network. The notation is not very intuitive, but it is a very fast operation and saves on writing. We will also see that no zeros are used and to express a bit masks, but its equivalent in hexadecimal, much faster to write than a string of ones and zeros. In case of doubt, We can always use a calculator that makes us transform basic binary to hexadecimal.

-Caso USB_READ_MESSAGE. “We sent” content “replyBuf” the PC using a USB-variable v “usbMsgPtr”, we left the function telling the length of the string to send, v-USB will handle shipping.

-Caso USB_SET_SERIAL. We value 9 the variable “operation”, we will use later, and continue processing.

-Caso USB_SEND_MESSAGE. We write a “buffer” data you send us the host. in dataLenght we calculate the number of bytes that we have been sent, if greater than the buffer we use, we cut our surplus. We left the function returning USB_NO_MSG, you call the function which will treat these data.

usbFunctionWrite is responsible for reading the data that the host sends us, *data is a pointer to a string of bytes, and len is the length of the chain. As we drive each byte of the string sent, We check the value of the variable “operation” and store the data in the chain that keeps the serial number, or keeping the response buffer as 9 the 0. At the end we left the function returning a valos indicating whether the operation was completed successfully.

Principal function

This is the main function of the program, We define the serial number calling Setserial the value containing serialNum, we declare a counting variabla, We define the behavior of the B and D ports “or” and we set up a microchip timer to count a time lapse.

TCCR1B represents the timer one ATMEGA chips, we say that the bit is activated WGM12, and this set the timer to count and do an operation on a flag every time you have reached the limit of the account. TIMSK1 is the timer interrupt mask one, OCIE1A is a bit that indicates whether the interruption is activated or not, we put a one in that bit to say that this interruption will be used.

activate the “guardian” for each second read the chip, This allows that if we have programmed wrong firmware, we can reset it to change the program, otherwise we could never use it again.

We called the v-USB function usbinit preparing the apparatus for use as a USB device, It is it communicates with drivers USB-lib and tells the host what kind of device is, how it is called and how we will use it. We started a cycle of 500ms where VUSiBino and PC are prepared to be understood, and we tell the PC that we have connected and list us. These are functions of v-USB. after that, We allow interruptions activate.

Now we define time units, OCR1A put on record a derivative of the value we attach to prescaled clock TCCR1B. In commented source code are possible values. Summarized very cursory way, what we do is tell the TCCR1B timer by dividing the clock frequency (16MHz) between a value (256) and use that figure as time reference, and the frequency that will handle the timer 62500 Hz, in OCR1A we say count to 62 (0.000992 seconds) Cambier before the interrupt flag. At datasheet del atmega, this Article, the this shipment They explain in detail how these timers work.

The following is an infinite loop, he “The main loop” will be repeated while the microcontroller is powered on or off “programming mode”. You not have too, a call to usbpoll() to keep the connection and check the status of the variable “operation” for cambier when the serial number needed. This could have done above, in function “usbFunctionWrite”, but I was sorry to leave empty loop. Besides the control function of interruptions that have to investigate further.

By the end we leave the routine called by the interrupt activated before. An interrupt is an event that stops the normal flow of a program to perform an operation. They are the oldest and most useful features of programmable circuits, but considering that stop a program to do something in the middle of execution, They are delicate. If interrupts handle any data that you use the program, we must be very attentive to this fact, since the interruption can be activated at any time of execution and cause a disaster if we are not careful.

To handle an interrupt code will use the definitions of the AVR library, ISR indicates that the code below is executed when an interrupt is triggered, brackets say who that interruption, in our case “TIMER1_COMPA_vect”, interrupt vector comparator in the timer A 1. In the above code we define the timer 1 would have a frequency of 62500Hz and that each 62 skip the counter cycles OCR1A. TCCR1B as we said it would be compared and that would trigger the interruption TIMSK1, we each 0.000992 seconds this interruption will be processed. Here is a guide very well done on interruptions AVR.

What we do when activated is to add another counter, Counter check that, Flicker first bit is active in sw_led and if so whether the interruption was called a hundred times (nearly a tenth of a second), If so we do two things, We change the status LED and the last bit of the variable LED. The latter by check only variables. To make this change in bits, we will use another basic logical operation, he “xor”, if a bit is zero and the other is zero, stays zero, if a bit is one and the other is zero, passes a one, and if a bit is one and also oto, passes a zero, or simply that if they are equal sets a zero and a one-if different.
This is your truth table.

A^B 1 0
1 0 1
0 1 0
In the next shipment we will see the part of the “host”, PC program which will handle the VUSiBino. We explain how to use the functions of v-USB and usbLib to communicate, and a little over creating and using dialogue windows.




Source code.


VUSiBino Demo en Github


Leave a Reply