- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In my application Psoc4 has to serve a device that could be configured in SPI or parallel mode during runtime. In SPI mode pin named D0 has to be configured as MTSR, D1 has to be configured as SS, D2 has to be configured as SCLK and D3 has to be configured as MRST. In parallel mode D0...D3 are part of the parallel IO (D0...D7) offering bidirectional IO. How to implement this switch on the fly?
Solved! Go to Solution.
- Labels:
-
PSoC 4 MCU
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @RuGl_1600761,
To achieve this, you need to write the registers of the GPIO manually for it to behave as a software controlled GPIO. You need to set the HSIOM so that the functionality is firmware controlled GPIO, set the drive modes and write the data registers for output/read the PS register for input.
The following code toggles between UART and normal GPIO functionality on pin P3.0 and P3.1 -
if(mode == 0)
{
/* Write the HSIOM for UART functinality */
val = CY_GET_REG32(CYREG_HSIOM_PORT_SEL3);
val = val | 0x00000099;
CY_SET_REG32(CYREG_HSIOM_PORT_SEL3, val);
/* Set the drive mode */
val = CY_GET_REG32(CYREG_GPIO_PRT3_PC);
val = val | 0x01;
val = val & 0xFFFFFFFE;
CY_SET_REG32(CYREG_GPIO_PRT3_PC, val);
UART_Start();
UART_SpiUartPutArray("Hello", 6);
CyDelay(100);
}
if(mode == 1)
{
UART_Stop();
/* Write the HSIOM for software controlled GPIO functinality */
val = CY_GET_REG32(CYREG_HSIOM_PORT_SEL3);
val = val &0xFFFFFF00;
CY_SET_REG32(CYREG_HSIOM_PORT_SEL3, val);
/* Set the drive mode */
val = CY_GET_REG32(CYREG_GPIO_PRT3_PC);
val = val | 0x3F;
val = val & 0xFFFFFFF6;
CY_SET_REG32(CYREG_GPIO_PRT3_PC, val);
/*Write the data register for toggling the pin */
val = CY_GET_REG32(CYREG_GPIO_PRT3_DR);
val = val |0x03;
CY_SET_REG32(CYREG_GPIO_PRT3_DR, val);
CyDelay(500);
/*Write the data register for toggling the pin */
val = CY_GET_REG32(CYREG_GPIO_PRT3_DR);
val = val & 0xFC;
CY_SET_REG32(CYREG_GPIO_PRT3_DR, val);
CyDelay(500);
}
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @RuGl_1600761,
To achieve this, you need to write the registers of the GPIO manually for it to behave as a software controlled GPIO. You need to set the HSIOM so that the functionality is firmware controlled GPIO, set the drive modes and write the data registers for output/read the PS register for input.
The following code toggles between UART and normal GPIO functionality on pin P3.0 and P3.1 -
if(mode == 0)
{
/* Write the HSIOM for UART functinality */
val = CY_GET_REG32(CYREG_HSIOM_PORT_SEL3);
val = val | 0x00000099;
CY_SET_REG32(CYREG_HSIOM_PORT_SEL3, val);
/* Set the drive mode */
val = CY_GET_REG32(CYREG_GPIO_PRT3_PC);
val = val | 0x01;
val = val & 0xFFFFFFFE;
CY_SET_REG32(CYREG_GPIO_PRT3_PC, val);
UART_Start();
UART_SpiUartPutArray("Hello", 6);
CyDelay(100);
}
if(mode == 1)
{
UART_Stop();
/* Write the HSIOM for software controlled GPIO functinality */
val = CY_GET_REG32(CYREG_HSIOM_PORT_SEL3);
val = val &0xFFFFFF00;
CY_SET_REG32(CYREG_HSIOM_PORT_SEL3, val);
/* Set the drive mode */
val = CY_GET_REG32(CYREG_GPIO_PRT3_PC);
val = val | 0x3F;
val = val & 0xFFFFFFF6;
CY_SET_REG32(CYREG_GPIO_PRT3_PC, val);
/*Write the data register for toggling the pin */
val = CY_GET_REG32(CYREG_GPIO_PRT3_DR);
val = val |0x03;
CY_SET_REG32(CYREG_GPIO_PRT3_DR, val);
CyDelay(500);
/*Write the data register for toggling the pin */
val = CY_GET_REG32(CYREG_GPIO_PRT3_DR);
val = val & 0xFC;
CY_SET_REG32(CYREG_GPIO_PRT3_DR, val);
CyDelay(500);
}
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Hari wrote:
Hi @RuGl_1600761,
To achieve this, you need to write the registers of the GPIO manually for it to behave as a software controlled GPIO. You need to set the HSIOM so that the functionality is firmware controlled GPIO, set the drive modes and write the data registers for output/read the PS register for input.
The following code toggles between UART and normal GPIO functionality on pin P3.0 and P3.1 -
if(mode == 0) { /* Write the HSIOM for UART functinality */ val = CY_GET_REG32(CYREG_HSIOM_PORT_SEL3); val = val | 0x00000099; CY_SET_REG32(CYREG_HSIOM_PORT_SEL3, val); /* Set the drive mode */ val = CY_GET_REG32(CYREG_GPIO_PRT3_PC); val = val | 0x01; val = val & 0xFFFFFFFE; CY_SET_REG32(CYREG_GPIO_PRT3_PC, val); UART_Start(); UART_SpiUartPutArray("Hello", 6); CyDelay(100); } if(mode == 1) { UART_Stop(); /* Write the HSIOM for software controlled GPIO functinality */ val = CY_GET_REG32(CYREG_HSIOM_PORT_SEL3); val = val &0xFFFFFF00; CY_SET_REG32(CYREG_HSIOM_PORT_SEL3, val); /* Set the drive mode */ val = CY_GET_REG32(CYREG_GPIO_PRT3_PC); val = val | 0x3F; val = val & 0xFFFFFFF6; CY_SET_REG32(CYREG_GPIO_PRT3_PC, val); /*Write the data register for toggling the pin */ val = CY_GET_REG32(CYREG_GPIO_PRT3_DR); val = val |0x03; CY_SET_REG32(CYREG_GPIO_PRT3_DR, val); CyDelay(500); /*Write the data register for toggling the pin */ val = CY_GET_REG32(CYREG_GPIO_PRT3_DR); val = val & 0xFC; CY_SET_REG32(CYREG_GPIO_PRT3_DR, val); CyDelay(500); }
Best regards,
Hari
thanks Hari.
I found the documentation of HSIOM register. But how to connect the SPI is not clear to me
I can not find the description of ACT_1 in data sheet. All I can find in datasheet about using port pins is this list
but no explanation how to use. Could you help me how to connect SCLK to P0.4 ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My two SPI connects this way. Second SPI module (master) connects
P0.3 MTSR; P0.4 SCLK; P0.5 MRS;
third SPI Module (slave) having only MRST (SDI input) on P0.6
The sclk and slave select of third spi is shared with second spi. The slave select is avaliable on P4.2
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can take a look at the architecture trm for the device. In my case, I tried in a 4000S device and the architecture trm shows the hsiom matrix.
Best regards.
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ok I find this table that tells me ACTIVE_1 is the connection to SPI (SCB)....There are several SPI available having connections to outside world (MISO,MOSI,SCLK,SS)
In The SCB chapter I find everything about the SPI module but not how to connect to the IO pins.... I think the only possibility for would be to do bit bang 😫
I will try to generate a schematic (TopDesign) and search for the HSIOM setting in the project.... Hoping to find the register settings....somehow reverse engineering 😡
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I searched the files (trying reverse engineering) found a lot of defines in the cyfitter.h and some routines that might set the ports in cyfitter_cfg.c... but nothing that I can identify how to connect the sclk of SPIM_2 to the dedicated pin (p0.4)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note that fixed function SCB (non-UDB) has dedicated output pins that can be connected to the specific GPIO. This means the SPI.SS can be connected to specific pins only, MOSI to certain pins, and so on.
In your case as well, you can see that you need to assign a value of 15 or 0xF, to the HSIOM register if you need to use SPI functionality in a particular pin. You can check this data, for the functionality supported by each pin, in the datasheet under the Pinouts tab.
Having said that, this is applicable if you are not using DSI. If you are using DSI for connection (not fixed function block), then this does not hold true and it becomes easier to simply look at the value that PSoC Creator assigns and copy the same. You can check the default value of a pin, if you want to see how PSoC Creator assigns the value, in the cyfitter_cfg.c file inside the cyfitter_cfg function. In my case, you can see the HSIOM default configuration here -
You can see that the default HSIOM configuration for port 2, where I put an SPI slave block, is "CY_SET_REG32((void *)(CYREG_HSIOM_PORT_SEL2), 0x0000FFFFu);", that is 0xFFFF. P2.0, 2.1, 2.2, and 2.3 are the SPI pins in my case and it has assigned a value of 0xF for each of those pins.
Please let me know if you face any further difficulty.
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found some thing similar in the cyfitter_cfg.c
/* HSIOM Starting address: CYDEV_HSIOM_BASE */
CY_SET_REG32((void *)(CYDEV_HSIOM_BASE), 0x00330000u);
CY_SET_REG32((void *)(CYREG_HSIOM_PORT_SEL2), 0x00000333u);
CY_SET_REG32((void *)(CYREG_HSIOM_PORT_SEL3), 0x0000EE00u);
CY_SET_REG32((void *)(CYREG_HSIOM_PORT_SEL4), 0x00300000u);
CY_SET_REG32((void *)(CYREG_HSIOM_PORT_SEL5), 0x00300000u);
CYDEV_HSIOM_BASE seem to be the same as CYREG_HSIOM_PORT_SEL0 (port 0) but the 0x00330000 does not fit to my assignment SPIM_2 -> (p0.03=out(MOSI); po.4=OUT(SCLK); p0.5=IN(MISO))
Using the table for HSIOM_PORT_SEL0 I get the 3 for P0.4 and P.5 and the 3 is DSI_GPIO and a 0 for all the other pin -> GPIO... what is DSI_GPIO ?? SO I do not think that this is the right place ???
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
#define CYDEV_HSIOM_BASE 0x40020000u
#define CYREG_HSIOM_PORT_SEL0 0x40020000u
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried a similar configuration and the MISO line is getting an HSIOM value of 0. All others are having HSIOM config of 3. Can you check if P0.3 is connected to MISO or MOSI?
And I tried debugging and the configuration is the same as the one given in cyfitter_cfg API.
Can you try this out and let me know it works? You can use the same value of HSIOM for SPI configuration.
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
0.3 is MISO and 0.4 is MOSI. I will do the configuration and try to catch the register setting by debugging...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In that case, the configuration is correct. You need to write 0x03 on all lines and 0x00 on MISO line.
Note that you are seeing this difference because the SCB is implemented using the UDB block and not the fixed function SCB component present in PSoC.
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just set up my target configuration. I need two Receive and one transmit channel. So I have to use a slave and a master SPI, sharing ss and sclk.
unfortunately this does not work for the shared ss and sclk pins gives errors. So is bit bang than the only solution ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you require the SS and SCLK pins also to be used as firmware-controlled pins? The idea is still applicable if you require only the MOSI and MISO lines to be used by firmware.
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Connecting SS and sclk of slave SPI and master SPI and connecting both to port pins to connect to my DUT (SPI slave 2 inputs and two outputs) the fitter gives an error for I can not connect one sclk output of master spi to pin (for external spi slave) and to slave spi (internal)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks for your reply. This will solve my problem.
On competitor datasheet such information is contained in the data sheet. It would be great to easily find such an information by browsing to the device page, finding a link with a brief description... eg other vendor often has a list of links pointing to detailed description (with detailed examples) of the peripheral and how to use it in several modes while the datasheet itself has a reduced version.