Jun 18, 2010
With a handful of PSoC3 resources and an external capacitor, a Voltage controlled oscillator can be created.
t = C * V / I For example, if the maximum period value is desired to be 500uS for an input voltage of 2.5V, for an IDAC value of 1uA, the value of C can be calculated: C = (500uSec * 1uA) / 2.5V = 200pF
Rating:
(3.5/5) by 4
users
May 27, 2010
In the recent FAE Conference held in the 3rd week of May 2010, I had a chance to attend a session on “Analog Signal Chain” taken by our Analog experts Dennis and Mark. They showed some really cool tricks using the PSoC3 analog. Some of this stuff was really amazing.
Coming soon is an Application Note on this cool trick.
Rating:
(4.3/5) by 3
users
May 07, 2010
Last week end – this is my first visit to the US – I had a chance to visit the 17 Mile Drive in Monterey Bay. My friend and colleague Palani took a great risk and agreed to teach me to drive on the US roads, especially the freeway. The Teacher and the Student He taught me lane discipline, important road symbols, looking over shoulders before switching lanes, entering the freeway at 60mph (I would never dare do this in India) and many more. I did throw him a few scares by driving on the left side of the road a couple of times (deserted roads of course) and once changing lane without looking behind my shoulder. Thanks to his tutelage I have learnt the ropes and now I am able to drive in San Jose roads without getting honked at (just once in the past 5 days). The Lone Cypress Tree This is “The Lone Cypress Tree” which stands on a rock for more than 200 years (some web sites claim more than 250 years). I learnt from a colleague Don that this tree which stands as a symbol of stability weathering time is the inspiration behind the Cypress Logo.
Rating:
(4.5/5) by 2
users
May 05, 2010
In this new series I will share with you some of my favorite PSoC Hacks – like cool things you can do by simple register writes or fixes to some of known issues in PSoC.
However, the disadvantage with this method is that this occupies one CT block. If your design has PGAs INSAMPs or CMPPRGs that occupy all the CT blocks, then there is no place for the RefMux user module. There is another way – The Hacker’s way – to bring out AGND. See the block diagram of a CT block below.
The TestMux inside the CT block can be configured to connect the AGND to the Analog bus (The RefMux UM uses this resource). Provided a resource placed in the CT block does not use the Analog bus, the same CT block may be used to bring out AGND by enabling the TestMux using register writes. For example, if you have a PGA placed in ACB00, the TestMux in ACB00 can be used to connect AGND to the Analog Bus and to P0[5].
Rating:
(4.3/5) by 3
users
Mar 18, 2010
Above code shows the general program flow when using an USBFS user module to send data to the PC using an IN Endpoint. If you notice, the USBFS_LoadInEP function call before the while loop uses “USB_NO_TOGGLE” and the call inside the while loop uses “USB_TOGGLE”. What is this TOGGLE and NO_TOGGLE? What is the significance of these constants? I can understand from the above code that the first time I call the USBFS_LoadInEP function, I have to use NO_TOGGLE option and TOGGLE for further transactions. Why is it so? These are some of the questions a first time user of USB faces. In the USB bus, data is transferred from the Peripheral to Host and vice versa using Data Packets. A data packet comprises of a DATA0 / DATA1 flag, the payload data and the CRC of the payload data. The DATA0 / DATA1 flag is used to synchronize the data delivery. Whenever a data packet is delivered, the receiver checks the DATA flag with its own internal flag. The transaction is successful only if the flag matches. At the time of enumeration, both the peripheral and the host set the Data flag to DATA0. When the peripheral sends the first data packet, it sends it with DATA0 flag. The host on receiving the packet verifies that the received packet has the DATA0 flag and its own flag is also DATA0. So, the transaction is successful. Immediately, the host toggles its internal flag to DATA1. The peripheral when sending the next data packet should also toggle its own data flag and send the data packet with Data1 flag. This toggling continues on all successive transactions.
In the PSoC, the constants USB_TOGGLE and USB_NO_TOGGLE tell the USBFS_LoadInEP function whether toggle the DATA flag before sending the data to the host. When the USB is started and enumeration is complete, the USB hardware sets the DATA flag to DATA0. As the very first data packet should go with DATA0, the DATA flag should not be toggled and hence the USB_NO_TOGGLE option should be used. All further transactions will require the DATA flag to be toggled and should use the USB_TOGGLE option.
Rating:
(4.8/5) by 10
users
Mar 08, 2010
One major issue that most people complain about Cypress website is the inefficiency of the search engine. It is very difficult to locate the desired information using the default search engine. For example, typing "change uart baud rate" in the keyword search box returns 1221 results. The search result contains everything from Data sheets to Application notes, but the KB article that I was looking for, "Changing UART Baud Rate on the Fly" appeared on the 10th page of the search result as the 901st entry. This makes it almost impossible to locate any information.
But all is not bad. There is good news. Google search is available as an alternate search engine in Cypress website. In the search result page, you can find a link to Google search on the top right corner "Search Tip: Didn't find what you were looking for? Try our Google Search". I clicked on the Google Search link and... Voila!! The KB that I was looking for is now the very first entry in the search result.
I hear you asking "Then why not make Google Search as the default search engine?" I got news that the web team is working on this and you should see Google as the default search engine in a couple of weeks' time. So, looking for some information on Cypress website? Google it!!
Rating:
(4.3/5) by 3
users
Mar 01, 2010
Many times in applications using the Watchdog timer, there may be a requirement to detect if a reset occurred due to Watchdog or POR / XRES and the application may either start fresh in case of POR / XRES or recover and start executing from the state when the watchdog reset occurred. DETECT THE SOURCE OF RESET The first requirement is to find out the source of reset. This can be done by checking the WDRS bit in the CPU_SCR0 register. This bit is set in case of a watchdog reset event. The below code in the beginning of main.c can be used.
In order to recover from a watchdog reset and resume the application, it is necessary that the Global variables be preserved when the watchdog reset occurs. This can be done by setting the IRAMDIS bit in the CPU_SCR1 register. When this bit is set, all the cells marked “??” in the below table are preserved during a Watchdog reset (taken from Technical Reference Manual Section 3).
Add the below code in the beginning of main.c to preserve the content of these RAM locations. When using C as the programming language, the boot.asm sets all the global variables to 0x00. This has to be disabled. The boot.asm has a constant “C_LANGUAGE_SUPPORT”, in the beginning. Set this constant to 0 to disable the global initialization. Change the value of the constant in boot.tpl in the project folder, save boot.tpl and Generate Application. As “boot.asm” is generated from boot.tpl, the change will now reflect in boot.asm. Only RAM locations from 0x03 are preserved when IRAMDIS is set. Locations 0x00, 0x01 and 0x02 will still get reset. So, no global variable should be placed in these locations. This is highly unlikely to happen though. By default all the global variables are placed in the area “bss”, which follows the areas “virtual_registers” (used by the compiler to store virtual registers) and “InterruptRAM” (used for user module variables). These areas will mostly occupy the locations 0x00 to 0x02 and more. In the remote possibility that both these areas are empty and “bss” starts from 0x00, you will have to create a custom area and place it at a location above 0x02, and place all the locals in this area. More details about placing globals in the desired RAM location can be found in this KB article. The location of the RAM areas can be checked in the project map file (with .mp extension) in the “output” folder in the project. Only RAM Page-0 gets cleared by resets and need be preserved by IRAMDIS bit. In devices with more than 256 bytes of RAM, Page-1 and above are not changed by a watchdog reset. So, locating all the global variables in RAM Page-1 or above will not require setting the IRAMDIS bit. ADDING SOME MORE RELIABILITY What if the event that caused the watchdog reset (RF interference or a power supply spike), also corrupted some of the global variables? We need to be able to detect this and start the program normally. Create a checksum of all the global variables that are critical to the program and store it in another variable. Every time one of the global variables is updated, update the checksum as well. On watchdog reset, calculate the checksum of all the global variables and compare it with the checksum variable. If the calculated value matches the stored value, then the global variables are intact and the process may proceed to recover from the last state. If the checksum values do not match, then the process can start from beginning. The code in the beginning of main.c will look something like this:
Rating:
(4.5/5) by 4
users
Feb 25, 2010
Recently, there was an article in Hindustan Times (a leading Indian Newspaper) titled “Swamy and Friends”. It is about my long time friends and colleagues Narayana and Geethesh.
Our friendship goes back 15 years when we were neighbors in Mysore in the late nineties. Narayana was working as a Data Entry Operator in Central Excise of India; Geethesh was the Head of Department of the Electronics in a very small Polytechnic. Narayana had a very strong logical mind which made him a great programmer, but absolutely no electronics background. Geethesh being a lecturer had a strong hardware background. During a leisurely conversation, I suggested them to combine their talents and take part in the Circuit Cellar Design contest. Their combination clicked and they won Honorary Excellence in their very first contest. There was no stopping them after that. They became PSoC consultants and then joined Cypress India as the first PSoC Applications Engineers - now the PSoC Applications team is 20+ strong. From a guy who had absolutely no electronics background - he knew nothing about resistors, capacitors, voltage and currents - today Narayana is an expert in capacitive sensing. He talks about Delta Sigma modulators, PRS generators, EMI etc, holds a patent for implementing a matrix keypad with minimum number of sensors and plans to file a few more. He is my one stop for reference for capacitive sensing. Geethesh today is part of the Technical support team leading a team of 6 engineers and is a mentor who trains and guides the young engineers in the team. I attribute their success to their hard work, sincerity and perseverance and am proud to be their friend. Thank you PSoC for bringing us together!! Swamy and Friends - Hindustan Times Article
Rating:
(4.8/5) by 4
users
Feb 19, 2010
A couple of weeks back I and my colleague Kannan - the guy who gave me the idea for the Dithered DAC - had been to BITS Pilani Goa campus for conducting a PSoC3 workshop. We conducted the workshop during the Quark 2010 Tech Fest for which Cypress is one of the sponsors. 96 students attended the workshop. In the morning we had a theory session on PSoC3 architecture. In the afternoon, we had three hands on sessions where students created PSoC3 projects starting from basic blink an LED using firmware to creating two out of phase PWMs and making an LED to brighten and dim from the phase shift. It was a great experience to be in college and teaching students. Seeing the enthusiasm of the students and the way they were enjoying college life, I got a nostalgic feeling about my college days 18 years back. If only I could turn time back... (sigh...) Here are a few photos from the workshop. Quark 2010 Mascot The theory session by Kannan The Practicals Also, on this occasion, three fighter planes from the Idian Navy presented an air show. It was awesome to see the three jets flying at Mach speed spewing colored smoke from their tails and performing various maneuvers with split second timing. Here are a few photos.
Rating:
(4.5/5) by 2
users
Jan 15, 2010
After I published my video on Connecting Multiple Wired Hardware Bus in PSoC Creator, I received a feedback from PSoC Sensei that there are easier methods to get this done. He even took the trouble to create a small video of screen capture showing how to do this and sent this to me. Based on his feedback, here is an updated version of the video. Thank you, PSoC Sensei!
Rating:
(4.5/5) by 2
users
Jan 14, 2010
When I was working on the project to test the High Resolution Dithered DAC, I had to connect two control registers to the input of a 2:1 8 bit wide mux and the output of this mux to the Data bus of the DAC. After many failed attempts to create a bus connection, one of the PSoC3 geeks taught me how to do this in the PSoC Creator. I created this video so that it may be useful to others who come across the same requirement. Hope you enjoy the video. An updated version of this video is available in this post.
Rating:
(5/5) by 1
user
Dec 16, 2009
When using the UART user module in the PSoC 1, the most important parameter for the UART is the clock. The user module data sheet says the clock to the UART should be 8x the baud clock. So, for a 9600 baud rate, the clock to the UART should be 8 x 9600 = 76.8KHz. In PSoC 1, this clock has to be derived from the SysClk or SysClk * 2. Let us take SysClk for this case and assume a SysClk of 24Mhz. To get a frequency of 76.8KHz from 24MHz, the required divider is 312.5. Unfortunately, we cannot have a fraction in the divider and have to round off to 312 or 313. For a divider of 312, the resulting clock is 76.923KHz. This gives rise to a plethora of questions. Is this clock accurate enough? Will I get bit errors because of the deviation in the clock? What is the maximum tolerance allowed in the clock to UART? Before we get into the answer to the question, let us first derive the maximum error allowed in the UART clock. Picture below shows the UART RX line and the internal 8x clock. The UART data transfer starts with a Start bit, 8 data bits, optional parity bit and ends with a Stop bit.
Ideally, the Receiver samples the RX line at the mid-point of every bit. If the UART clock has 0% error, then the sampling will happen exactly at mid-point of the Stop bit. But as the UART clock will have a tolerance, depending on the +ve or –ve error on the UART clock, the sampling will happen earlier or later than the mid-point on every bit. This error keeps accumulating and will result in the maximum error on the Stop bit. Ideally the maximum error allowed on the Stop bit would be + ½ a bit, ie, 50% of the bit time. But practically, if we sample earlier or later by 50% of the bit time, we will be sampling at the bit transition. For systems that have higher bus capacitance and higher rise and fall times, this will create a problem. So, allowing for rise and fall times at 20% of the bit time, we have a room of +40% of the bit time in the Stop Bit. The tolerance allowed on the UART clock is 40% / (No. of Bits). For an UART with one Start bit, 8 data bits and one Stop bit, the maximum error allowed on the clock would be 4%. This 4% tolerance has to be split between the devices on the either side of the UART bus. For example, if a device on one side of the UART bus runs on a crystal at 100ppm, the device on the other side can have a clock tolerance of 3.99%. Remember, this 4% also is again subject to system performance. If you are running a very long cable and the UART at a very high baud rate, the rise and fall times may be more than 20% of the bit time and you will have lesser room for error. AT lesser baud rates and shorter cables, you will have more room for error. Now let us check the round off error introduced by the divider. For a 9600 baud, we use a divider of 312 on the SysClk which results in a clock of 76.923KHz against the requirement of 76.8KHz. The error introduced by this deviation is just 0.1% and is negligible. The next contributor to the error budget is the tolerance of the clock source which is the IMO. In most of the PSoCs (CY27x43, CY29x66, CY24x23, etc), the IMO has a tolerance of +2.5% over the full operating temperature. This is well within the 4% tolerance. Also, the PSoC boot.asm code writes a factory programmed trim value to the IMO trim register, which further reduces the error of the IMO to <1%. So, clocking the UART from the IMO will not introduce any problem. What about the devices which have IMO with a tolerance of >=4% (CY24x94, CY21x34 etc)? In fact, when you place an UART component in the CY24x94 device, the Design Rule Checker gives a warning that to use an UART, the device should be connected to the USB bus. When connected to the USB bus, the IMO gets synced to the USB clock and hence will become as accurate as the USB bus clock. When not connected to USB bus, it runs at 4% tolerance and hence this warning.
With the above considerations, a robust UART communication can be built in PSoC 1.
Rating:
(4.8/5) by 4
users
Nov 28, 2009
In Part-1 we looked at the features of the PSoC1 GPIO. In this part, let us look at application scenarios. WRITING TO A GPIO PIN To control a GPIO using the CPU, first the GPIO pin should be set to StdCPU mode in the GPIO configuration window in device editor. This will clear the corresponding bit in the PRTxGS register disconnecting the pin from the Global bus. The drive mode should be set to any mode other than HighZ or HighZ Analog. Now the pin may be controlled by writing to the PRTxDR register. Following are some examples in assembly and C. Assembly Examples:
C Examples:
However, this method has a disadvantage that it is not portable. For example, let us say we have placed an LED on P0[5] and have used PRT0DR to control the LED. Later in the design cycle of the project, the LED is to be moved to P1[2]. Now we will have to search all the locations in the project where PRT0DR is accessed and change this to PRT1DR. Using Pin names will solve this problem. Below is the procedure. 1. Give a meaningful name to the pin to be controlled. For example “LED”
Now, if the LED were to be moved to any other port, the register definition in the psocgpiont.inc and psocgpioint.h files will be automatically updated by the PSoC designer and there will be no need to change the application code. READING A GPIO PIN Following are C and Assembly code examples to read from a GPIO pin. Either the PRTxDR can be directly used or register and mask names from psocgpioint include files can be used. In the below examples, an input pin named SWITCH is read.
C Example:
Notes:
READ MODIFY WRITE INSTRUCTIONS AND SHADOW REGISTERS P1[0] - PullUP, Connected to a switch. 1 has been written to the bit in PRT1DR to enable the pullup Now, the following instruction is used to switch off the LED
The above instruction is a Read/Modify/Write instruction, ie, it first reads the pin states (not the value written to PRT1DR register before), does an “AND” operation with the mask and then writes back the result to PRT1DR register. If the switch were pressed when this instruction is executed, the pin state of P1[0] would be 0, so the result of the operation would be Pin State: x x x x x x x 0 Bit-0 which drives the switch has been cleared in PRT1DR now and will never become high. This will result in the input pin stuck to 0, irrespective of the state of the switch. A workaround for this condition is using Port shadow registers. Declare a variable in RAM and initialize this variable in the beginning of code to the initial Port value. After this, do any Read/Modify/Write operation on this shadow register and then write the value of shadow register to the PRTxDR register.
WRITING A GPIO ISR Now, let us configure a GPIO pin for interrupt and write an ISR that increments a variable “IntCount”. In the Device Editor GPIO configuration, set the interrupt to the desired type. The PSoC Designer will take care of the PRTxIE and PRTxICx registers in the boot.asm code In main, enable the Global interrupt by using the M8C_EnableGInt macro In main,enable the GPIO interrupt by using the below code.
Whenever a pin is enabled for interrupt in the PSoC Designer Device editor, the IDE generates a file called psocgpioint.asm. This file has the place holder to write an ISR for the GPIO interrupt. The following code should be added within the user code marker in the ISR function.
If you would like to write the ISR in C, then do the following. Declare the ISR function using #pragma interrupt_handler
Write the interrupt handler function.
In the psocgpioint.asm file, place an ljmp instruction to branch to the C ISR
More about C ISRs can be found in this KB Article
Rating:
(5/5) by 7
users
Nov 28, 2009
GPIOs play an important role in creating a bridge between the internals of a microcontroller to the external world. Let us take a look at the important features of PSoC 1 GPIO and application scenarios. Because of the large amount of information to be covered, I have split this into a two part series. Part-1 is about various features of the GPIO like the Drive modes, GPIO registers, Interrupts and the PSoC Designer interface to configure the GPIO. This is mostly boring stuff from the Technical Reference Manual. If you would like to get to the interesting stuff, skip to Part-2 which covers application scenarios like writing to a GPIO, reading from a GPIO, Read Modify Write Instructions and writing a GPIO ISR. DRIVE MODES PSoC1 GPIO pins can be configured into one of 8 drive modes.
Strong and Slow Strong are used as outputs. The Slow strong mode introduces a slew rate control on the pin that increases the slope on the rising and falling edges of the pins thus reducing EMI and RFI radiations. HighZ mode is used as input for both analog and digital signals and also for analog output. HighZ Analog mode is used for Analog input and output. Remember, in the HighZ Analog mode, the Schmitt trigger circuit on the digital input path is disabled and hence the pin cannot be used to read digital signals nor will it generate interrupts. Pull Up, Pull Down, Open Drain High, and Open Drain Low can be used as Input as well as Output. An exception is when a pin is connected to the Global Input bus to route the signal to a digital block. When a pin is connected to the Global Input bus, it cannot be configured in Pull up or Pull down modes. REGISTERS The GPIO pins are controlled by various registers. Data Register: The state of a GPIO can be controlled / read by writing / reading the PRTxDR register. For example to make P1[5] HIGH, Bit5 of PRT1DR should be set. More about writing and reading GPIO pins in Part-2. Drive Mode Registers: There are three drive mode registers for each port that control the drive mode of the pins in a particular port. These are the PRTxDM0, PRTxDM1 and PRTxDM2 registers. The combination of the bits of these three registers decide the drive mode of a particular pin. For example, the drive mode of P2[3] will be decided the combination of Bit3 of PRT2DM0, PRT2DM1 and PRT2DM2 registers. Details can be found in the Technical Reference Manual. Global Select register: The PRTxGS register decides if a GPIO pin is under the control of the CPU or is connected to the Global In or Global Out bus. When the bit in PRTxGS register is cleared, the pin can be controlled by the CPU by writing to the PRTxDR register. When the bit in PRTxGS register is set, the pin is connected to the Global bus and connects to the internal hardware blocks. Interrupt Control Registers: PRTxIE, PRTxIC0 and PRTxIC1 are registers that control the interrupt mode of a GPIO pin. Each GPIO pin may be configured to generate an interrupt on Rising Edge, Falling Edge or a Change from Read event. The interrupt behavior of GPIO pins are controlled by the following registers. PRTxIE Register: This register enables or disables the interrupt for a particular GPIO pin. For example, if the interrupt has to be enabled on P1[5], Bit5 of PRT1IE register has to be set. When the interrupt type is selected in the GPIO configuration pane in the PSoC Designer device editor, the designer automatically sets the PRTxIE register in the boot up code. PRTxIC0 and PRTxIC1 Registers: These two registers are used in combination to choose between four options of interrupt type for each pin – Disabled, Rising Edge, Falling Edge and Change from Read. Following are the bit combinations of PRTxIC0 and PRTxIC1 registers. For example to configure P2[1] as a Rising Edge interrupt, Bit1 of PRT2IC0 should be cleared and Bit1 of PRT2IC1 should be set. When the interrupt type is selected in the GPIO configuration pane in the PSoC Designer device editor, the designer automatically sets the PRTxIC0 and PRTxIC1 registers accordingly in the boot up code. When the pin is configured for a Change From Read interrupt, an interrupt is generated whenever the state of the pin changes from the state that was read from the pin. So, to generate an interrupt from both rising and falling edges, whenever an interrupt is generated from the pin, a read operation should be performed on the PRTxDR register. Even if there is no requirement for such a read, a dummy read operation has to be performed for the interrupt to work. INT_MSK0 Register: Bit5 in the INT_MSK0 bit is the Mask bit for GPIO interrupt. Only when this bit is set, the interrupts raised by GPIO pins will be processed by the CPU. The device editor does not take care of setting this bit. This bit has to be set in the firmware. Notes:
PSOC DESIGNER – CONFIGURING A GPIO All the GPIO pins can be configured using the GPIO configuration window in the PSoC Designer device editor.
Name: Giving meaningful names to the GPIO pins will make the project more readable. For example, LED, SPI_MOSI, SPI_MISO, UART_TX etc. Giving names to the GPIO also will be useful in controlling the pins using the register definitions in the psocgpioint.h file. More about this later. Select: This parameter selects the mode of the pin like Analog Input, Global Input, Global Output etc. On specific pins, special functions like XTAL_IN, XTAL_OUT, I2C_SCL, I2C_SDA etc also will be available. When the type of pin is selected, the drive mode will be automatically be set. Drive: This parameter selects one of 8 drive modes for the pin. Though the drive mode will be automatically set according to the pin type selected in the previous parameter, it can be overridden. Interrupt: This parameters sets the interrupt type of the pin
Rating:
(4.3/5) by 6
users
Nov 10, 2009
Here is a video on PSoC Designer Getting Started. This shows how to create a PSoC Designer project to measure an analog signal using a 12 bit ADC and display on LCD. Also a PWM is configured for 1Hz output to blink an LED. Write to me your feedback to graa@cypress.com
Rating:
(4.4/5) by 8
users
Nov 06, 2009
A couple of weeks ago, I had written about a method to implement a High Resolution DAC using two 8 bit DACs. Recently I had a very interesting discussion with one of my colleagues and a good friend, a young and brilliant guy named Kannan. He showed me how to implement a high resolution Dithered DAC using a single 8 bit DAC, an 8 bit Mux, a couple of Control Registers and a PWM. It is amazing what you can do with the PSoC 3 hardware. Dithering is a widely used technique in Digital Processing where a noise is intentionally introduced into a system to increase the resolution of the system. Say we have an 8 bit DAC with a full scale value of 255mV. Each count of the DAC represents 1mV. What if we wanted an output of 1.25mV from the DAC. Switch the DAC output between 1mv and 2mV keeping the output at 2mV 25% of the time and 1mV 75% of the time, the average value of the output would be 1.25mV. For an output of 1.5mV, the DAC output should be maintained at 2mV for 50% of the time and 1mV 50% of the time.
Now let us see how this method can be implemented using the PSoC 3 hardware to create a 10 bit DAC.
Place an 8 bit voltage DAC. Select 1.020V (4mV / bit) as the range. Set the Data_Source to “DAC Bus” and Strobe_Mode to “External”. The output of the DAC can now be controlled using an 8 bit data bus and the output will be updated on the rising edge of the Strobe input. Place a Multiplexer from the Digital >> Logic category. Set number of input terminals to 2 and terminal width to 8. The multiplexer can now switch between two 8 bit data buses. Place two control registers from the Digital >> Registers category. Set the number of outputs to 8. Connect the 8 bit data bus of the Control registers to the input of the Multiplexer. Place a PWM, with a period of 3 and compare type set to “Less than”. The output of the PWM now can be controlled to 0%, 25% and 75% duty cycle. Connect the output of the PWM to the control input of the Mux. Use the same clock of the PWM as a strobe to the DAC. The hardware is now ready. void main() The range of the DAC now is 0 to 1020 counts; each count representing 1mV, subject to some offset and gain error inherent in the 8 bit DAC. Quoting my brilliant friend “I bet this cannot be implemented with any other controller out there in the market!!”
Rating:
(4.8/5) by 10
users
Oct 25, 2009
Most if not all of the microcontroller designs that involve analog signal processing will require an ADC to convert an analog signal into a digital value that can be processed by the CPU. PSoC 1 has a vast selection of ADCs that can be used depending on the application, ADCINC, ADCINCVR, ADCINC14, DELSIG8, DELSIG11, DelSig to name a few. Most of the users, beginners to experts face some or other problem while using an ADC like ADC not completing the conversion, ADC result always zero, ADC result incorrect etc. Below are Five Golden Rules that will help you to tame the PSoC 1 ™ ADC. GLOBAL INTERRUPTS A PSoC 1 ADC is a combination of analog and digital blocks and the CPU. An SC block configured as a modulator converts the input analog signal into a digital bit stream. A counter is used to count the time the bit stream is high for a given period of integration time. A timer or a PWM is used to set the integration time. At the end of integration cycle, the timer or PWM generates an interrupt and the processor reads the counter inside the interrupt.
When Global Interrupt is disabled, the CPU will not respond to the timer’s (or PWM’s) interrupt to read the ADC result. So, the ADC would never complete the conversion. Any instruction, for example, while(ADC_fIsDataAvailable() == 0); that waits for the ADC result to complete will execute forever Golden Rule No.1 – Always enable Global Interrupt ANALOG POWER The Analog power parameter under the Global Resources sets the power to the SC blocks and the reference.
For the ADC to work correctly, always select the power settings “SC On / Ref Low”, “SC On / Ref Medium” or “SC On / Ref High”. Selecting a reference with “SC Off” or “All Off” will result in the ADC not working. The Reference power should be selected so that the Reference Generator is able to provide adequate power to the Analog blocks. The power to the Reference section should always be equal to or greater than the highest power used by any analog block in the design. For example, if you have a PGA and an ADC where the PGA operates at Low power and the ADC at Medium power, the Reference power should be set to SC On / Ref Medium or SC On / Ref High. Golden Rule No.2 – Always provide power to SC Blocks and set appropriate Reference Power. COLUMN CLOCK AND DATA CLOCK The ADC has a parameter called “Clock”. This selects the clock source to the Digital section of the ADC. The column clock for the SC Block should be set to the same value as that of the “Clock” parameter. In the picture below, the Clock parameter is set to VC2. So, the Analog Column clock should also be set to VC2. If the Column clock and Data clock are not the same, the output of the ADC will not be correct.
Golden Rule-3: The Data Clock and Column Clock should always be equal CLOCK PHASE The output of Switch Capacitor blocks is not a continuous signal. SC blocks have two phases of operation. Phase-1 is the charge acquisition phase when the input signal is sampled. During this phase, the output of the SC block is 0. Phase-2 is the charge transfer phase when the acquired charge is transferred to the output and the output is proportional to the ratio of input and output switch capacitor cell values. So, the output of the SC block is valid only during Phase-2. Application Note “AN2041 - Understanding Switched Capacitor Blocks” is a very good source of information on this subject. If an ADC’s input is connected to the output of another SC Block, say a 3 Op-Amp Instrumentation Amplifier or a Filter, the output of this source SC block is 0 during Phase-1 of the SC Block operation. The ADC modulator which is also an SC Block samples the input signal on Phase-1. Because of this, the ADC will always see 0V at its input and will always produce an output of 0. Under this circumstance, the ClockPhase parameter of the ADC should be set to “Swapped”. Now, the ADC modulator will sample its input on Phase-2 of the SC Block cycle when the input is valid. This will produce the correct ADC result. If the input to the ADC is a continuous signal from a CT block, the Analog bus or a direct pin, then the ClockPhase parameter can be set to either “Normal” or “Swapped” Golden Rule-4: Always set the correct value for the ClockPhase parameter WAITING FOR THE RESULT INSIDE AN ISR Many a time, you may want to initiate an ADC conversion inside the ISR of another user module, say a timer or counter and process the output of the ADC inside the ISR. The code may look like this: void TimerISR (void) // This is an ISR The above code will result in the program stuck in the while loop waiting for the ADC result to be available. When an ISR is entered, the Global Interrupt is disabled and is enabled only when the ISR exits. So, inside an ISR no other interrupts will be serviced. The ADC requires the interrupt to work for its conversion to be completed. As the ADC interrupts will not be serviced inside the TimerISR, the ADC conversion would never complete. Re-enabling Global interrupt inside the ISR would be a solution. But this is not preferable as this could also result in nested interrupts locking the CPU inside ISRs forever. So, do not wait for an ADC result to be available inside another ISR. Instead set some flag inside the ISR and do the ADC conversion in the foreground. Golden Rule-5: Never wait for the ADC result inside an ISR Follow the above five Golden Rules and see the PSoC 1 ADCs work happily for you!!
Rating:
(4.6/5) by 9
users
Oct 12, 2009
PSoC3 has 8 bit voltage and current DACs. Higher resolution DACs may be created by combining two 8 bit DACs, one for MSB and one for LSB and summing their outputs together. The DAC section of the TRM shows how to chain two 8 bit DACs to get a 12 bit DAC.
The MSB is implemented using an 8 bit DAC configured for 2.040mA full scale. Each bit of the MSB DAC now corresponds to 8uA. To create a 12 bit DAC, we need to extend the resolution by four bits and each bit should be equal to 1/16 of the MSB DAC, which is 0.5uA. This can be implemented by using Bits 2 to 5 of another 8 bit DAC configured for a 32uA output. The schematic diagram of a PSoC3 project to create a high resolution current DAC is shown below.
Below is the code that is used to split the 12 bit DAC value and update the MSB and LSB DACs.
Rating:
(4.3/5) by 6
users
Oct 05, 2009
Any microcontroller project will have the need to control a GPIO pin using a CPU. Applications could be simple ones like switching On/Off an LED, a relay, a buzzer etc to complex ones like generating a software PWM, bit-banging I2C protocol etc. There are many options to control a PSoC3 GPIO in firmware. Let us take a look at some of these options and their pros and cons. Option-1: Use Port in APIs When a Digital Output Port component is placed in the project, the PSoC Creator generates API functions to control the port pin. The function used to write to the pin is <Pin Name>_Write. For example, for a Port Pin component named Out1, Out1_Write(1); // Set the pin Pros: The advantage of using the API function is the ease of programming and portability. Cons: The disadvantage of using this method is the high number of processor cycles taken to update the pin. Following is the listing of the Output1_Write function. In this method, the port data register is accessed in the external data memory space using the PHUB. For every Port Pin placed in the schematic, a header file <Pin Name>.h has the declarations for the Port data register and the mask. For a Port Pin named Out1, the Port data register and the mask are Out1_DR Out1_MASK respectively. For example: Out1_DR |= Out1_MASK; // Set the pin Pros: This type of access takes less processor cycles than the API function call. The example code #1 above results in the below compiled code. ; Out1_DR |= Out1_MASK; ; SOURCE LINE # 41 Cons: There isn’t any great disadvantage of using this method other than the fact that this method is still slower than Option-3 below, and sacrifices some amount of readability compared to Option-1. Option-3: Control the pin using the SFR register space In this method, the port data register is accessed directly in the SFR register space. There are two SFRs that need to be controlled. SFRPRTxDR: The register bits control the bits of the corresponding port. For example the value in Bit5 of SFRPRT0DR register controls the state of P0[5]. SFRPRTxSEL: Setting the corresponding bit in this register, enables the control of the port pin through the SFRPRTxDR register. For example, if Bit5 of SFRPRT0SEL is set, then the state of P0[5] is controlled by the value of Bit5 of SFRPRT0DR register. If the bit is cleared, the port can be controlled only through the PHUB interface. These registers are declared in PSoC3_8051.h header file under the cy_boot folder in the workspace explorer. Details of these registers may be found in PSoC3 Technical Reference Manual under Section 4.6.4 – I/O Port Access SFRs. For example, to switch On/Off P1[5] // First enable SFR access for P1[5]. This has to be done only once in the beginning of code // To switch on // To switch off // To toggle Pros: This is the fastest way to modify the port pin state. This takes a single direct memory access instruction and takes 3 CPU cycles to execute. Cons: Not portable. If you relocate a Port Pin component in the schematic to a different GPIO port, then all the code that access the pin through SFRs have to be rewritten. Summary: 1. If the project does not have any timing restrictions and you prefer readability over execution time, use Option-1
Rating:
(5/5) by 3
users
Sep 27, 2009
Here is my first attempt in creating a technical video, where I have explained how to create an ADC project to measure and display an analog voltage for PSoC3 using the PSoC Creator. Watch it in full screen mode for a clear view of the screen capture. Please watch and send me your feedback to graa@cypress.com.
Rating:
(4.8/5) by 4
users
Sep 22, 2009
The E2PROM user module is a very handy user module for emulating an E2PROM in the Flash program memory. Here are some key points to remember while using the E2PROM user module. My apologies for the very long article. Wanted to keep it short, but as I kept adding information this grew into a 1000+ word blo(n)g.
User Module Parameters: Starting Block: This specifies the flash block number where the E2PROM begins. Always place the E2PROM in the last blocks of the flash. For example, in a 32K device, a 256 byte (4 blocks) E2PROM should be placed in blocks 508 to 511. So, the first block should be 508. This ensures that maximum space is available for the code memory and prevents clash between code memory and E2PROM. Remember to modify the flashsecurity.txt file and set the protection level of the flash blocks to “U” or “R” w w w w w w w w w w w w w w w w ; Base Address 7800 E2PROM Write Function: To write data to the E2PROM, use the E2PROM_bE2Write function. The prototype of the function is char E2PROM_bE2Write(WORD wAddr, BYTE *pbData, WORD wByteCount, char Temperature); wAddr: This is the location in the E2PROM where you would like to write the data. A very common mistake made is people enter the physical address of the flash location. The value should be relative location in the E2PROM, not in flash. For the example mentioned above, to write data to the first location in the E2PROM, the value of wAddr should be 0x0000, not 0x7F00. *pbData: This is the pointer to the buffer that holds the data you want to write to the E2PROM. If the data is not in a char buffer, then you use typecasting. For example, if to write a structure MyStruct, typecast the pointer to (char*)&MyStruct. wByteCount: This is the number of bytes to be written to the E2PROM. More about it later. Temperature: The Temperature parameter is used by the E2PROM API to calculate the flash write pulse width. At higher temperatures the flash has to be written with a smaller pulse width and at lower temperatures with a longer pulse width. The flash will meet its maximum endurance and write cycles if it is written with the correct pulse width. If the device is going to operate within a temperature range of 0 to 50 degrees, it is ok to pass the value of 25 for temperature. But for operation over the full temperature range, use FlashTemp user module and pass the correct die temperature. If this is not done, either the data retention or the flash endurance will be compromised. If the temperature value passed is less than the operating temperature, the flash will be written with a longer pulse width than required. This will reduce the flash endurance. On the other hand, if the temperature value passed is higher than the operating temperature, the flash will be written with a lower pulse width than required. While this does not affect the endurance, the data retention will be less than the guaranteed 10 years. The bE2Write function returns the status of the write operation. A return value of 0x00 means the write was successful. -1 means error in writing which could be because the flash is write protected. -2 means stack overflow. Always check the return value in your program to make sure that the write was successful. E2PROM writes always take place in 64 byte blocks. When you write less than 64 bytes of data, it is called a partial write. The flash write API first reads all the 64 bytes from the flash block into RAM, modifies the desired bytes and writes back the 64 bytes of data to Flash. This results in a heavy RAM overhead requiring 103 bytes of stack space, whereas a full block write takes only 32 bytes of stack. In devices with only one RAM page, the global variables and stack share the 256 bytes. If the RAM usage of the globals is high, this could lead to stack overflow errors while performing partial writes. Under such condition, it is always advisable to perform a 64 byte write. Even if you are writing say 10 bytes of data, set the ByteCount to 64. The first 10 bytes will be the actual data followed by data from subsequent RAM locations. Check out the E2PROM user module data sheet under the section “Efficient Memory Usage” for more details. Initializing the E2PROM with data: Many a times you may be using the E2PROM to store calibration data or any other system related data, where you would like to load the E2PROM with some initial values while the device is programmed. Following method may be used to achieve this. In C: Use the “#pragma abs_address” directive. For example, if the E2PROM is placed in the last flash block in a 32K device, and if you wanted to initialize the first 10 bytes with some value: #pragma abs_address 0x7FC0
In assembly: area eeprom(rom, abs) A Practical Situation – Storing and Retrieving a Structure Let us take a look at a practical E2PROM usage where a calibration structure is stored, read and written in the E2PROM. Create a typedef for the structure
typedef struct CAL_STRUCT RAM variable to store the calibration values
CAL_STRUCT CalValuesRam; Initialize the E2PROM with initial values:
#pragma abs_address 0x7FC0 Now to read the value from the E2PROM to the RAM you can use either the E2PROM_Read function: E2PROM_E2Read(0x0000, char* &CalValuesRam, sizeof(CalValuesRam)); Or: CalValuesRam = CalValuesEeprom; To write the values from the RAM to E2PROM E2PROM_bE2Write(0x0000,(char*)&CalValuesRam, 64, 25);
Rating:
(4.8/5) by 4
users
Sep 18, 2009
This is one of the most common problems users face with an ADC while debugging. The ADC result is always corrupt after you hit a breakpoint in the program. Why does this happen? Let us take a look at how an ADC is created in a PSoC. Except for the SAR6 ADC, which uses a single Analog block, all other PSoC ADCs (ADCINC, ADCINCVR, DelSig, DELSIG8/11 etc) are a combination of Analog and Digital blocks. The block diagram of an ADCINC12 is shown below.
An SC Bloc configured as an analog modulator converts the input analog signal into a digital bit stream, whose On Time / Off Time ratio is proportional to the input signal. 0V - 50% on, 50% off A counter integrates this bit stream for a fixed integration window set by a timer, and at the end of the integration cycle, the CPU reads the value in the Counter which is the ADC result. The hardware implementation of the digital integrator is different in different ADCs, but the concept is the same. For the ADC result to be correct, the CPU has to read the value from the counter exactly at the end of the integration cycle. If it fails to do so, the counter will continue counting the bit stream and will result in an incorrect ADC result. When a break point is hit while debugging, the CPU halts. But the analog and digital blocks continue to run in the background and the counter would be counting many ADC integration cycles. So, naturally when CPU resumes execution after the breakpoint, the value read from the counter would be wrong. If you are debugging some other section of the program that does not have any dependency on the ADC result, then just ignore this. When you program the device and the program runs continuously, the ADC result would be correct. If you are debugging a section that depends on the accuracy of the ADC result, then here are some things that you can do. 1. As the program is running, dynamically set a breakpoint after the instruction that reads the ADC result, by left clicking on the left margin of the code window (left side of the Line number). When the program halts, the value read from the ADC would be correct. Now clear the breakpoint, run the program and dynamically place the breakpoint again. Happy debugging!!
Rating:
(4.3/5) by 3
users
Sep 15, 2009
At last, after a long wait and lots of suspense, PSoC3 and PSoC5 have been officially announced. I sat down to do my first project, measure an analog input signal with an ADC, pass the result through an FIR filter, convert to voltage and display on the LCD. Or should I call this is my pseudo first project as I have been in some of the PSoC3 training sessions and had worked with some very early versions of the PSoC Creator. The download and installation of the PSoC Programmer and PSoC Creator went quite smooth without a hitch. But for some reason, the registration happened only after a few retries and “Invalid user name and password” errors. Working with the PSoC Creator is fun. The Creator looks like a hybrid of PSoC Designer and OrCAD. In PSoC Designer, you place user modules in the correct analog/digital blocks, use the Analog / Digital interconnect nets to connect between blocks and pins etc. In the Creator, you draw a schematic instead.
You place the required resources, connect them using wires, and configure the pin outs in the pin configuration window. Voila, the device is ready. Writing code is similar to PSoC Designer where you use the Library API of the components - the user modules of PSoC Creator. If you have worked with PSoC Designer, it should be quite easy to learn PSoC Creator. Once I had the schematic and the pin configurations done, writing code was quite simple and I was able to get the project working in less than 20 minutes. Overall, my pseudo-first experience with the PSoC Creator was great. I relived the thrill of working with PSoC Designer version 1.31, back in 2002. There is so much to explore - New IDE, new processor cores, new compiler, new debugger… I am loving it. Hello World. PSoC3, PSoC5 and the Creator are here and are here to stay!!!
Rating:
(5/5) by 3
users
Sep 10, 2009
One another passion I have other than PSoC is bird watching and photography. I enjoy trekking into jungles or waterbodies during week ends with my Canon DSLR camera and 300mm telephoto lens and shoot birds (with my camera ofcourse). It is a great experience seeing all those colorful birds in their natural habitat and is a great stress buster. Here are some photos from my collection. Spot Billed Pelican in Flight - Shot at Karaji lake,Mysore, Karnataka, India, a waterbody thousands of migratory birds come from all over the world every year. It took 1/2 an hour and 10's of shots to ge this perfect photo of the majestic bird in flight. Due to dwindling habitat of water bodies, this bird is now classified as "Near Threatened"
Australian Ibis - Resting after flight - Shot at Karanji Lake, Mysore
Yellow billed babbler - This is a very noisy bird and is always found in groups of 7 to 10. Also called as 7 sisters. When I was showing this photo to my boss, he observed that the bark that the bird is sitting looks like a snake's head.
Rose Ringed Parakeet - I shot this in Birla Institute of Technology in Pilani Rajasthan which I had visited to conduct a PSoC workshop. This bird patiently posed for me till I got the perfect shot.
Red Wattled Lapwing - Shot at Birla Institute of Technology, Pilani. This bird which is considered to be very shy always tries to keep distance from human beings. But surprisingly, this bird came quiet close so that I could get a very clear shot.
Send me your comments to graa@cypress.com.
Rating:
(4/5) by 4
users
Sep 07, 2009
“Can’t Acquire Device”, “Verify Failed”, “Checksum Error”, “Device not in database”. These are some of the errors the PSoC Programmer throws at users when programming a PSoC In System. When you dedicate the P1[0] and P1[1] pins exclusively for ISSP, there usually is no problem in programming the chip on board. But the trouble begins when you share P1[0] and P1[1] for other functions. The most commonly encountered problem in ISSP is when P1[0] and P1[1] are used for I2C. In programming mode, both SCLK and SDATA pins of the PSoC are configured in Pull Down mode with an internal 5.6K pull down resistor. There is no issue with the SCLK line as the programmer always drives the SCLK line. But things are different with the SDATA line. When the programmer is reading information (like device ID, verify, checksum etc), the PSoC has to drive the SDATA line. The external I2C pull up resistor forms a potential divider with the internal pull down resistor and does not allow the PSoC to drive LOW on the SDATA line. This results in a plethora of errors mentioned before. There are various approaches to solve this problem.
If the SDATA or SCLK line is configured as an input pin and is driven by a low impedance source, this will load the programmer. So, always use the SDATA and SCLK pins as output pins driving a high impedance load. This will prevent the programmer getting loaded. Do not use direct capacitive loads on the ISSP lines as this will affect the rise and fall times of the programming signals and will affect programming. Check out AN2014. This application note provides some details about the ISSP programming, pin loading etc. Happy ISSP Programming!!
Rating:
(4.7/5) by 3
users
Sep 04, 2009
Hi Everybody, I am M. Ganesh Raaja and I work for Cypress Semiconductor as a Principal Applications Engineer. I completed my Diploma in Electronics and Communications Engineering in 1992 and since then have worked in various jobs like servicing computer peripherals (huge floppy drives, huge hard disks, huge line printers etc), design engineer in a power electronics company designing UPS, design engineer in an Instrumentation company designing industrial sensors and having my own company developing custom industrial automation products using 8051 controllers. In 2002, I came across PSoC when searching for a microcontroller for an advanced panel meter design. You could call it love at first sight. Though that panel meter design never went through, it completely changed my life and brought me and PSoC together. I bought the CY3205 development kit with the ICE-4000 emulator and started playing around with PSoC. Since then I have been addicted to this device and have been doing various PSoC related things like writing application notes, conducting PSoC seminars for customers, writing user module code, training engineers on PSoC etc. Another addiction I have is posting regularly in PSoC Developer forums as “graaja”. In the past 6 months though, my activity there has reduced due to various reasons, which I plan to restart soon. In this blog I would like to share with you many of my experiences with PSoC, tips and tricks of using PSoC, interesting articles I come across on PSoC and microcontrollers in general etc. Welcome. Let’s Talk PSoC!!
Rating:
(4.3/5) by 4
users
|
Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms and Conditions of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms and Conditions of this site. Cypress Semiconductor and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.











Tags: 

.png)









.jpg)













