Manual Use of Pin After SCB Disable

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
PrMa_264311
Level 3
Level 3
First like received

I have encountered some puzzling behavior of my CY8C4125. The situation is this. Sometimes I need I2C, sometimes I need to bit-bang the output. This functionality is mutually exclusive, so they never overlap. As mentioned in a previous post, I have to enable then disable I2C because something about it modifies the program space, which would corrupt a continuously running program CRC check. I2C then remains inactive until I need it. I2C is on SCB 1. This places SCL on P0[4] and SDA on P0[5]. 

   

With the I2C disabled, I should be able to take control of the pins and manually bit bang them for whatever I want. Unfortunately that does not appear to be the case. I have verified that when the program is running and I2C is disabled that register HSIOSEL4 is correctly set up to 0x0. This means the pins are not connected to any internal peripheral but are firmware controlled. I then manually force the pin configuration to output but calling the Pin_SetDriveMode() function and setting it to OD_LOW. Finally, I write to the data register by calling Pin_Write(). I have inspected memory and verified that the data registers (0x40040000) are set correctly. I cannot verify the drive mode registers because, while I know where the register is (0x40040008), there is no information in the TRM about the register. But let's assume it is correct if the Pin_SetDriveMode() function works. If I set the pin high, I see the bits in the DR change. Same for low. But the output does not change at all.

   

So I tried another experiment. I removed all I2C functionality and simply placed two firmware controlled pins called I2C_scl and I2C_sda with drive modes set at OD_LOW. All code is the same. Now I can bit bang them without any problem.

   

I then looked closely at the registers in memory view. I have attached an image of those registers in both cases. As best I can tell, the registers are set up exactly as they should be, but the outputs do not work. Am I halucinating? Reading the TRM wrong? Reading the memory watch wrong?

   

Any thoughts would be appreciated.

0 Likes
3 Replies
lock attach
Attachments are accessible only for community members.
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

I found the attached in architecture TRM.

   

 

   

Also this, dealing with PSOC 3/5, may give some clues on PSOC 4 -

   

 

   

http://www.cypress.com/?rID=57571

   

 

   

Regards, Dana.

0 Likes
PrMa_264311
Level 3
Level 3
First like received

 FYI, as of this morning, there is an updated TRM for the PSoC 4 that is not correctly linked on the cypress website. The latest TRM can be found at http://www.cypress.com/?docID=44837. The link accessible from PSoC Creator ( PSoC Creator > Help > Documentation > PSoC Technical Reference Manuals takes me to http://www.cypress.com/?rID=57350. On this page, clicking on the link PSoC® 4 Architecture TRM.pdf takes me to http://www.cypress.com/?docID=43536) is the old file from April, not June.

0 Likes
PrMa_264311
Level 3
Level 3
First like received

I finally found the problem. When the I2C bus is used, the high-speed I/O matrix (HSIOM) is engaged. Simply stopping the I2C by calling I2C_Stop() does not disconnect the HSIOM from the pins. The HSIOM must be manually disconnected. This is found on page 56 section 7.10 of the PSoc 4100/4200 Family TRM (Rev. *B). In case anyone was wondering, step 3 should be, "Change the corresponding field in HSIOM_PORT_SEL_x to drive the pin by the data register, PRTx_DR." Further, if you carefully read the new register TRM from July 24, you will see that setting the HSIOM_PORT_SEL_x fields to 0x00 disconnects the HSIOM from the pin.

   

 

   

In conclusion, everything worked when I added the following code after shutting down the I2C:

   

 

   

                *(uint32*)CYREG_PRT0_DR = *(uint32*)CYREG_PRT0_PS;

   

                *(uint32*)CYREG_HSIOM_PORT_SEL0 = 0x00000000;

   
        
   
    I can get away with this HSIOM setting because no other internal peripherals (SCBs) are connected to the pins on this port.   
0 Likes