PSoC Sensei Blog | Cypress Semiconductor
- void SetInterruptMode(uint32 interruptMask)
Used to control which interrupt sources are able to generate an interrupt. There are defined values for each of the sources. For the TCPWM an interrupt can be generated based on a terminal count or based on either a compare value or a capture. This function doesn't need to be called if the interrupt sources are configured using the component customizer. This function modifies the INTR_MASK register for the block.
- uint32 GetInterruptSourceMasked()
This is the function that you want to call when the interrupt fires. It allows the interrupt routine to determine which interrupt source caused the interrupt. The same defined values are used to indicate which source caused the interrupt. This function returns the value of the INTR_MASKED register for the block.
- uint32 GetInterruptSource()
Similar to the GetInterruptSourceMasked() function except it doesn't take into account which mask bits are enabled or disabled. This function is useful when polling for the condition to occur instead of being triggered by an interrupt. This function returns the value of the INTR register for the block.
- void ClearInterrupt(uint32 interruptMask)
Once the condition has occured, the interrupt bit will stay set until the bit is cleared. This function is used to clear the specified bits. This is implemented by writing a one bit to the INTR register.
- void SetInterrupt(uint32 interruptMask)
With this function the interrupt can be forced to occur without requiring the actual hardware condition to occur. It will cause the interrupt condition to be seen by the hardware and software in the same way as it would be if the actual hardware interrupt had occurred. This is useful to test out the operation of the interrupt code. This function writes to the INTR_SET register for the block.
One of the enhancements to clock generation that was introduced with PSoC 4 is the ability to have fractional clock dividers. By default all the clock dividers are integer clock dividers. For PSoC 4 that means that you can generate a clock whose frequency is the frequency of the High Frequency Clock (HFCLK) divided by a 16-bit integer. For small dividers that can result in large jumps between adjacent available clock frequencies. For example if HFCLK is running at 48 MHz, then the available clocks are 48 MHz, 24 MHz, 16 MHz, 12 MHz, ... If you want a clock that is 14 MHz, then you would need to run HFCLK at a multiple of 14 MHz (14, 28, or 42 MHz). In some cases that approach works fine, but it also changes all the other dividers in the system. An alternative solution is to divide by a fractional amount. PSoC 4 supports division by a 16 bit integer (for fractional dividers this must be at least 2) and a fraction which is a multiple of 1/32nd. In this example you can get close to 14 MHz by dividing by 3 14/32 which yields a frequency of 13.96 MHz. Fractional dividers do however introduce jitter in the clock, so it is important to understand how they work and when you might want to use them.
The first step to understanding fractional clock dividers is to understand integer dividers. In PSoC the clock dividers are implemented off of the source clock rising edge. If the integer divider is even, then a 50% duty cycle clock is generated with the clock low for half the divider value clock periods and the clock high for the same amount of time. Here is a picture of a 3 MHz HFCLK being divided by 4 to produce a 750 kHz clock.
For those that have used PSoC 3 or PSoC 5LP and are now using PSoC 4, you'll notice that there are some changes between what can be done with clocks on the different devices. There are a few new restrictions and several new capabilities. In this post I'll take a look at using clocks in the UDB array and with pins.
The first change is that clocks can only be used as clocks. They cannot be used as data signals. In PSoC 3 and 5LP this was possible, but discouraged. In PSoC 3 and 5LP the clock signals were available as clocks and also as routed signals. The reason it was discouraged to use them as routed data signals is that the timing of these signals is not guaranteed. That means that setup and hold is not known when a routed clock is used as a data signal and clocked by another clock. With PSoC 4 this discouraged usage is just not allowed. PSoC 4 only has the clocks distributed on the low skew clock lines and those are only connected to clock inputs. As an example the following circuit will generate an error with PSoC 4.
Although this isn't the most useful circuit, what if I really needed to implement this circuit? The solution is to convert the clock signal to a data signal. This is easily done with a toggle flip-flop and a clock signal running 2x faster.
This circuit is perfectly legal. In this case a 4 MHz clock is used instead of a 2 MHz clock. The toggle flip-flop toggles with every 4 MHz clock edge resulting in a data signal that is a perfect square wave at 2 MHz. The resulting signal also has a known timing relationship. Because of that, this is also the circuit that should be used for PSoC 3 and 5LP designs as well.
One common debug application for routed clocks is to send the clock to a pin along with a data signal. This can be done just to observe the clock during debugging. In PSoC 3 and 5LP this is done simply by hooking a clock to an output pin.
This is not allowed on PSoC 4 since clocks can't be used as data signals. However, PSoC 4 has some new pin capabilities and they allow the clock to be sent directly to a pin. In fact there are a bunch of new clocking capabilities for pins. Right now I'll just take a look at the one that allows this function to be implemented with PSoC 4.
This configuration looks a little odd, but it does exactly what is desired. The 12 MHz clock in this case is sent directly to the pin. The clock signal needs to be sent to the out_clk terminal and the output pin terminal is just tied high. To get to this point start with a standard output pin and then change the configuration as shown here:
This causes the output pin to output the clock instead of the data signal. Then make this second configuration change:
This configures the pin to use the clock that is being provided as the out_clk as the output clock signal for the pin.
With those changes and the signal connections shown the clock signal is once again visible on the pin.
Now that all the design work has been done for the square root component, we can do the work of creating the component in the tool. First, create a new project in PSoC Creator. Then, create a new component by right clicking your project in the Components tab, selecting "Add Component Item..." and selecting "Verilog File":
Now, load up the Datapath Configuration Tool and open the Verilog file that was created in the previous step. Select Edit->New Datapath. Choose the Instance Type to be cy_psoc3_dp8, give it a name, and click OK.
This will create a single 8-bit datapath with all of the default settings. Now we can configure the CFGRAM to implement our 8 operations. I've highlighted the important entries for each operation, as well as any that changed from the default:
Now we can configure the static portion of the datapath configuration. There isn t much to do here. We need to make sure that our comparison is configured correctly, and that both FIFOs have dynamic mode enabled. Everything else can stay with the default values.
Now, save the file and close the Datapath Configuration tool. The last step is editing the Verilog file to add the state machine parameter values from the last blog post, the actual state machine and a few other pieces of Verilog to complete the logic of the component.
We'll define a few more control signals: A fifo_dyn wire to determine when the FIFOs are CPU/DMA-controlled vs. datapath-controlled, an eoc wire to indicate when computation has completed, and a cs_addr wire to dynamically select the operation. Note that this is simply the lower 3 bits of the state. We'll also need wires for each of the two conditions that we plan on using in the state machine:
The state machine is relatively simple. It can be pieced together from the state diagram:
Finally, we need to hook up our control and condition wires to the datapath:
We now have a component that configures the datapath to compute the square root of an 8-bit number. In the CJCU_Isqrt component, CJ has extended this implementation to 16, 24, and 32 bits, as well as providing APIs. For information on how to extend datapath functionality to multiple bytes, see PSoC Creator 213. To see how to design component APIs for datapath components, see PSoC Creator 214.
- 1 of 6
- next ›
ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". CYPRESS SEMICONDUCTOR AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY CYPRESS SEMICONDUCTOR. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM CYPRESS SEMICONDUCTOR.
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.