Embedded Systems/Cypress PSoC Microcontroller

From Wikibooks, open books for an open world
Jump to navigation Jump to search

The Cypress PSoC microcontroller, like all microprocessors, has its own quirks.

When you can't figure something out, and this FAQ doesn't help, the forums at

are a good place to start.

User Documentation[edit | edit source]

Cypress PSoC FAQ[edit | edit source]

(If the answers I've sketched in are incorrect, *please* correct them).

Which PSoC to use[edit | edit source]

Some people recommend that hobbyists use the largest and most capable chip available in a DIP package—as of 2008-09, that is the CY8C29466 28-DIP.

CY8C29466 28-DIP—This is the same chip as in the CY8C29466 28-SSOP or 28-SOIC, and similar to the CY8C29566 44-TQFP, CY8C29666 48-SSOP or 48-QFN, and CY8C29866 100TQFP. The difference aside from the packages is the number of I/O pins. These parts have more Flash (32 KByte Flash) and more RAM (2 KByte RAM) and more digital blocks (16) and more analog blocks (12) than any other PSoC available (except the 27xxx series has the same number of analog blocks).

CY8C27143 8-DIP: more Flash (16 KByte Flash) and more digital blocks (8) and more analog blocks (12) and just as much RAM (256 bytes) of any 8-pin PSoC.

CY8CNP102: not yet available (as of 2008-09), but expected to have 256 KByte non-volatile storage and 2 KByte RAM.

(analogous to Embedded Systems/PIC Microcontroller#Which PIC to Use)

Many PSoC development boards are available for under $100 each. They include:

other FAQs[edit | edit source]

Q: It's not working!
A: Have you gone through the "Software Checklist: Tips on Using PSoC" by Zlatko Saravanja, 2004 ? Tips on using the PSoC ? PSoC(R) Technical Reference Manual (TRM)? "Getting Started with PSoC (READ THIS FIRST) - AN2010"?

Q: I'm having problems trying to use my PSoC MiniProg to program a CY8C26443.
A: The Miniprogrammer does not support the 25/26 families. You will have to use ICE-4000 or the ICE-cube. Or switch to a chip that the MiniProg does support, such as the 27/29 families. [FIXME: make a list of chips, and mark each with "Y -- known to work with MiniProg", "N -- doesn't work with MiniProg", or "? -- unknown"]. http://www.psocdeveloper.com/forums/viewtopic.php?t=2057 http://www.psocdeveloper.com/forums/viewtopic.php?t=2022 (Should we make this a table, with the various programmers -- m8cprogs open hardware, MiniProg, ICE-cube, etc. vs. the various chips?).

interrupt handler[edit | edit source]

Q: How do I write an interrupt handler in C?
A: See [1] "Software Checklist: Tips on Using PSoC". Also, inside the PSoC IDE, choose "Help", "Documentation", then "C Language Compiler User Guide". More discussion: http://www.psocdeveloper.com/forums/viewtopic.php?t=2089 and "Tips on using the PSoC" http://www.psocdeveloper.com/old/index.php?page=8&mode=article&k=11 http://www.psocdeveloper.com/forums/viewtopic.php?t=1902 http://www.psocdeveloper.com/forums/viewtopic.php?t=2102 http://www.psocdeveloper.com/forums/viewtopic.php?t=2099 http://www.psocdeveloper.com/forums/viewtopic.php?t=2089

warning: area 'myproject_RAM' not defined[edit | edit source]

Q: I'm getting the message:

warning: area 'myproject_RAM' not defined in startup file './obj/boot.o' and
does not have an link time address.

How do I get rid of that warning?
A: (from http://www.psocdeveloper.com/forums/viewtopic.php?t=1761 ) Open the boot.tpl. In the end, you will see many areas defined in RAM. Add the following line below the already existing RAM area declarations, just above the AREA bss declaration: AREA myproject_RAM (RAM, REL, CON) Then save the boot.tpl file and "Config" >> "generate application".

lookup table[edit | edit source]

Q: How do I create a lookup table in assembly language?
A: See http://www.psocdeveloper.com/old/index.php?page=8&mode=article&k=10 (Um ... don't you also have to disable "code compression" during that table?)

gotchas[edit | edit source]

Q: Any gotchas I should watch out for?
A: "Tips on using the PSoC" http://www.psocdeveloper.com/old/index.php?page=8&mode=article&k=11

simulator and other programming languages[edit | edit source]

Q: What alternatives are there to the (free) PSoC Designer and the ImageCraft PSoC C compiler ? (Because they haven't yet been ported to Linux)
A1: m8cutils: http://m8cutils.sourceforge.net/ Werner is developing an assembler and a simulator and a programmer for Linux [2] [3] http://www.psocdeveloper.com/forums/viewtopic.php?t=1616
A2: Forth/PSoC Forth: Christopher Burns wrote a PSoC Forth. The source code is available at http://www.psocdeveloper.com/tools/misc_dev_tools/ . As of 2007, David Cary is maintaining it at Forth/PSoC Forth (was: http://forthfreak.net/index.cgi?M8cForth ). This Forth compiler will work with Linux, Mac, Windows, Solaris, Palm, and even VT-100 dumb terminals.

I/O pins[edit | edit source]

Q: How do I make output pins Hi and Lo ?
A: Usually you connect the output pins to some digital "module" (such as a PWM block). If none of the "modules" do what you want, you can set them in software—see The GPIO reference http://www.psocdeveloper.com/articles/fundamentals_of_psoc_gpio/ the GPIO Read Write example project http://www.psocdeveloper.com/docs/example-project.html GPIO Help http://www.psocdeveloper.com/forums/viewtopic.php?t=83 http://www.psocdeveloper.com/forums/viewtopic.php?t=1950 (Warning: Be aware that the PRTxDR register is write-only—you can't read back from that register. If you read from the PRTxDR address, you are directly reading the value at the pins, which is often *not* what you just wrote. If you incorrectly assume they will be the same, you will sooner or later be bitten by the read-modify-write problem.). (Warning: "you cannot read a port that is configured for "interrupt on change from last read" from main code and have the ISR feature work reliably." See http://www.psocdeveloper.com/forums/viewtopic.php?t=2094 ). "How to set a single port pin?" http://www.cypress.com/portal/server.pt/gateway/PTARGS_0_652034_739_205_211_43/http%3B/sjapp20/cf_apps/design_supports/forums/messageview.cfm?catid=3&threadid=18055 PSoC I/O Pin-Port Configuration - AN2094 http://www.cypress.com/portal/server.pt?space=CommunityPage&control=SetCommunity&CommunityID=285&PageID=552&shortlink=DA_240474 "Mr. Zee's intro to GPIO", "Basic fundamentals of GPIO" by mrzee http://www.psocdeveloper.com/forums/viewtopic.php?t=2058 http://www.psocdeveloper.com/forums/viewtopic.php?t=1667

Q: What should I do with pins I'm not using? A: Nothing. The Designer will leave them in high-impedance mode by default. They'll be perfectly happy if left floating. If it really bothers you, set them to pull-up or pull-down.

QThe XRES should be connected to ... what ?
A: Although it has an internal pull down it is good practice to connect it to ground via a 470,1K,... ohm resistor.

I/O pins[edit | edit source]

Q: How do I read the state of a single digital input pin?
A: Usually you connect the input pins to some digital "module" (such as a timer block). If none of the "modules" do what you want, you can set them in software—see the GPIO references in the previous question.

interrupts[edit | edit source]

Q: How do I set up a digital input pin to trigger an interrupt? Where do I put the code to handle that interrupt?
A: ??? http://www.psocdeveloper.com/forums/viewtopic.php?t=1586 "How to determine source of GPIO interrupt" http://www.psocdeveloper.com/forums/viewtopic.php?t=1524

How many bytes of stack do I really need?[edit | edit source]

Q: I'm running out of RAM—How many bytes of stack do I really *need*?
A: the "stalkwalk" utility does static stack analysis http://www.psocdeveloper.com/forums/viewtopic.php?t=9 gives a conservative count of how many bytes are needed. (It still needs some work ...).

RS485[edit | edit source]

Q: How do I connect my PSoC to a RS485 bus?
A1: http://www.psocdeveloper.com/forums/viewtopic.php?t=1640 mentions "Interrupt on 9th bit ... Application Note AN2269 "Implement 9-Bit Protocol on the PSoC™ UART" ".
A2: Half-duplex issues are discussed at http://www.psocdeveloper.com/forums/viewtopic.php?t=1731 http://www.psocdeveloper.com/forums/viewtopic.php?t=2397

UART[edit | edit source]

Q: The UART isn't working! I'm pulling out my hair!
A: Please restate in the form of a question.

mixing C and assembly language[edit | edit source]

Q: How do I call a C function from assembly?
A: You can call C functions in assembly by adding an underscore before the function name. For example, if you want to call a C function called foo() from assembly you would use

 call _foo

. This applies for C functions that do not take any parameters. If you want to call functions that take parameters then you need to pass these parameters to the stack before calling it. The parameters are pushed from right to left and MSB first. Example: C function to be called:

 void foo(WORD Arg1, WORD Arg2)

assembly code:

 mov A,[Arg2 MSB]
 push A
 mov A,[Arg2 LSB]
 push A
 mov A,[Arg1 MSB]
 push A
 mov A,[Arg1 LSB]
 push A
 xcall _foo
 add SP,-4

interrupts[edit | edit source]

Q: How do I call a C function from an assembly ISR?
A1: The simple method: Use "#pragma interrupt_handler" to mark the C function. From the ISR side, LJUMP to the C function (don't bother pushing anything on the stack). Refer to the answer of question "How do I write an interrupt handler in C?". The C function marked with "#pragma interrupt_handler" can call normal C functions (and normal assembly functions) -- but normal C functions *cannot* call any C function marked with "#pragma interrupt_handler".

A2: If you insist that your assembly ISR *must* "call" a normal C function, it gets tricky.

You need to take care of saving and restoring virtual registers used by the C function. Open the .lst file and check what are the virtual registers used by the C function. For example, if the C function foo() uses virtual registes __r0 and __r1: (assumes void foo(void). See "How do I call a C function from assembly?" if foo has parameters.)

 mov A,[__r0]
 push A
 mov A,[__r1]
 push A
 xcall _foo
 pop A
 mov [__r1],A
 pop A
 mov [__r0],A

Apart from saving and restoring virtual registers, A and X also have to be saved and restored. In case you are using a program with LMM enabled, then the paging mode has to be restored to native paging before calling the C function and also the paging registers have to be saved and restored.

This is all stuff that the compiler would have handled automatically for you, if you had marked that C function with "#pragma interrupt_handler", and had your assembly language LJUMP to that C function.

object code size[edit | edit source]

Q: How can I optimize object code size generated by the PSoC C Compiler ?

A1: On MCUs with more than 256 bytes of SRAM, do not use LMM if at all possible. The overhead from page management is significant.

A2: Do not use 32-bit variables unless absolutely necessary.

A3: If possible, stick to 8-bit variables of type BYTE, and only use 16-bit WORDs if necessary.

A4: If readability does not overly suffer, try to only use global variables.

A5: Stay away from pointers to structures, and arrays of structures. This particularly means avoiding the passing of structure pointers to functions.

A6: Consider limiting the number of function parameters, and making common data global that can be accessed directly by all functions.

JTAG[edit | edit source]

Q: Does the PSoC do JTAG ?
A: No. But much of the JTAG functionality can be done other ways. PSoC boundary scan using "m8cbscan"

Q: Is there a way that the program running in the PSoC can modify the flash in that same PSoC? (instead of the normal process of burning the program into the PSoC, then never modifying the program) ?
A1: ... use the EEPROM module ...
A2: ... some tips in the "Flash Write Routine" thread ...
A3: ... Forth/PSoC Forth gives an example of a program running in the PSoC that modifies the flash in that same PSoC.

Further reading[edit | edit source]

  • Forth/PSoC Forth gives an example of PSoC assembly language
  • "Homemade MIDI turntable" by casainho very briefly shows a schematic and a photo of a PCB with a CY7C63723 microcontroller on it (inside an optical mouse) ... although the final project ends up using an Atmel AVR instead.