Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can Not get (2) PSRAM chips to work together #33

Open
jcoleman-oneaihealth opened this issue Nov 8, 2023 · 12 comments
Open

Can Not get (2) PSRAM chips to work together #33

jcoleman-oneaihealth opened this issue Nov 8, 2023 · 12 comments

Comments

@jcoleman-oneaihealth
Copy link

jcoleman-oneaihealth commented Nov 8, 2023

Hey AnatolSher , thanks for the help with getting the 1st PSRAM chip to work !

--

But now I am using Multiple PSRAM chips.

I stacked (2) chips.

PSRAM Wiring :

PB6 + PB1   CS     \/   +Vdd
      PB3   IO1/SO  IO3/Hold    PB5 
      PB4   IO2/WP      SCLK    PB0  
            Gnd-      SI/IO0    PB2 

1st Chip has CS connected to BP1 - with 100K resistor tied to V++.
2nd Chip has CS connected to BP6 - with 100K resistor tied to V++ also.

It works fine, if I ONLY Initialize PSRAM with CS PB1.

--

But if I disable PB1 cs as :

  /// DeSelect cs=PB1 : ///
  pinMode(      PB1 , OUTPUT );
  digitalWrite( PB1 , HIGH   );

Then ReInit PSRAM :

PSRAM_ReInit_CS( GPIOB , GPIO_PIN_6 );

static void  PSRAM_ReInit_CS( GPIO_TypeDef* gpio_N , int cs_N )
{
 //  __HAL_RCC_PSRAM_CLK_ENABLE();
 //  __HAL_RCC_GPIO_CLK_ENABLE();

/*  
  BRD PSRAM :
PB1   CS    \/   +Vdd
PB3   IO1/SO IO3/Hold    PB5 
PB4   IO2/WP     SCLK    PB0  
      Gnd-     SI/IO0    PB2 
*/

 //  __HAL_AFIO_REMAP_PSRAM_CS(GPIOB, GPIO_PIN_1);   // PB1 / CS   // CS 
  __HAL_AFIO_REMAP_PSRAM_CS( gpio_N , cs_N );   //  ..  CS   // CS 
 
  __HAL_AFIO_REMAP_PSRAM_CLK(GPIOB, GPIO_PIN_0);  // PB0 / SCLK // SCK 
  __HAL_AFIO_REMAP_PSRAM_D0(GPIOB, GPIO_PIN_2);   // PB2 / MOSI // SI/IO0 
  __HAL_AFIO_REMAP_PSRAM_D1(GPIOB, GPIO_PIN_3);   // PB3 / MISO // SO/IO1 
  __HAL_AFIO_REMAP_PSRAM_D2(GPIOB, GPIO_PIN_4);   // PB4        // WP/IO2 
  __HAL_AFIO_REMAP_PSRAM_D3(GPIOB, GPIO_PIN_5);   // PB5        // Hold/IO3 

  hpsram.Instance  = PSRAM;
 //   hpsram.Init.Div  = 2;    // - (160MHz) BAD DATA on Ips6404 - 
   hpsram.Init.Div  = 3;    // - (80MHz) WORKS on Ips6404 -
//  hpsram.Init.Div  = 0 ;  // => 0xFF ...
////   hpsram.Init.Div  = 4 ; // = 5 , = 8 ;
 ////  hpsram.Init.Div  = 15;  // = 2-15
////  hpsram.Init.Div  = 20;
////  hpsram.Init.Div  = 32;
  hpsram.Init.Mode = PSRAM_MODE_QSPI;

  if (HAL_PSRAM_Init(&hpsram) != HAL_OK)
  {
    Serial.printf("Init error...\r\n");
  }
}

=>
*** It Just Reads FFs from either PSRAM ... !!!

-- Maybe I need to DeInit PSRAM before Init_PSRAM() again ???

@AnatolSher
Copy link

AnatolSher commented Nov 9, 2023

Hello! It doesn't work that way. You need to use an analog bidirectional switch or digital equivalent. The signal on pin PB6 should switch banks. Double initialization of the PSRAM controller is also required. Separately for each bank
The scheme is something like this, without going into details
image

@jcoleman-oneaihealth
Copy link
Author

jcoleman-oneaihealth commented Nov 10, 2023

I tried that using a 74hc4051.
But it did not work.
I was thinking maybe it was too slow.

Whats wrong with just (2) gpio to (2) CS pins - instead of MUX ?

So, I tried with just :
PB1-> Ram1chip:CS
PB6-> Ram2chip:CS

That was the code above.
But it just spits out 0xFFs with PB6 as CS in ReInit()

@AnatolSher
Copy link

AnatolSher commented Nov 10, 2023

Whats wrong with just (2) gpio to (2) CS pins - instead of MUX ?

Because it doesn't make sense. The CS line is controlled by the PSRAM controller in hardware. We can only change the time that this line is held low level.
The multiplexer must be selected high-frequency. SN74LVC (TI) or ADG (AD)
Such multiplexers work well:
image

I don't understand why you need 2 banks, but you should simulate the standard connection of one bank

@jcoleman-oneaihealth
Copy link
Author

How about : SN74LVC138APW ?

@AnatolSher
Copy link

AnatolSher commented Nov 11, 2023

No. This is not the right chip for your purposes.
2 X SN74LV4053 is good
Might look like this:
image

You need to take care of the correct PCB wiring and draw the missing pull-up resistors and blocking capacitors
And there is no guarantee that such a solution will work in hardware :)
At your own peril and risk

PS. If you don't have enough RAM and you are a fan of C-SKY architecture, it's better to use this... maybe
image
$6 C-SKY Linux Development Board Features GX6605S Media SoC with C-SKY ISA

@jcoleman-oneaihealth
Copy link
Author

jcoleman-oneaihealth commented Nov 12, 2023

Why MUX every SpiRam chip pin to the GPIOs ?
If the SpiRam is Not Enabled via its CS - then all of that Chip IOs are disabled.

W806:            SpiRam #1 : 
               +-----------+
GB1  --------> | CS
       *-----> |   MISO
       |  *--> |  MOSI
       |  |    | ... etc
       |  |    +-----------+
MISO   |  |
GPIO --*  |       SpiRam #2 :   
GPIO --|--*    +-----------+
MOSI   *--|--> |  MISO
          *--> | MOSI
               | ... etc
GB6 ---------> | CS
               +-----------+

I dual connected each SpiRam Pin to the same W806 GPIO pins ,
except the CS pins were on separate GPIO pins (PB1 and PB6).

I could then Intitialize PSRAM / SpiRam # 1 , using SpiRam as CS->PB1 ,
-- then talked with SpiRam chip # 1 worked with good data.

But when I changed GPIO PB1 to Input ,
then Initialized PSRAM / SpiRam # 2 with CS=GB6 ,
-- the PSRAM just went to returning only FFs.

@AnatolSher
Copy link

AnatolSher commented Nov 12, 2023

Why MUX every SpiRam chip pin to the GPIOs ?
If the SpiRam is Not Enabled via its CS - then all of that Chip IOs are disabled.

First: Because I'm not sure that the PSRAM pins of the chip (d0-d3) will go to Z state when the CS signal is high.
Second: You cannot influence the CS line of the PSRAM memory controller. There is no HardSS or SoftSS mode as in the SPI interface
image
Eng:tCPH, CS high level minimum time setting, the unit is the number of AHB clock cycles, must be greater than 1, the specific time depends on Set according to the instructions in the same psram manual. If you are not sure, you don’t need to modify the default value.

Your approach to increasing capacity is good for software emulation of the PSRAM communication protocol.
Take a good logic analyzer and look in real time at what is happening at the pins of your dual assembly. Especially watch the CS line
If the PSRAM pins can go into the Z state, you can get by with one MUX (sn74lvc1g3157) and switch only the CS lines
Don't forget to connect CS and CS' to power via pull-up resistors

@jcoleman-oneaihealth
Copy link
Author

jcoleman-oneaihealth commented Nov 12, 2023

Yeah, got that.
Both CS lines are tied High via 100K resistors.

PSRAM # 1 Initializes and runs SUCCESSFULLY - even though both PSRAM chips are stacked - as the diagram above.

-- But I can not figure out how to switch to PSRAM # 2 successfully,
(and back to PSRAM # 1 ... etc).

I think it needs something to De-Initialize current PSRAM # 1 with CS=PB1 in the code.
-- Then I can Initialize 2nd PSRAM (with CS=PB6).

And vice-a-versa, to switch back to PSRAM # 1 again :
De-Initialize current PSRAM # 2 (with CS=PB6),
then i can Initialize PSRAM # 1 (with CS=PB1) again.

It may be slower, but I can switch back and forth between PSRAMs.
Just need to keep Initializing next PSRAM # .

--

Btw: Where are these located in the Libraries / Include Files (I can not find them) :
HAL_PSRAM_Init
PSRAM
PSRAM_MODE_QSPI
PSRAM_HandleTypeDef

@AnatolSher
Copy link

AnatolSher commented Nov 12, 2023

wm_psram.*
C:\Users\User\AppData\Local\Arduino15\packages\w80x_duino\hardware\XT804\0.0.5\cores\w806\include\driver
C:\Users\User\AppData\Local\Arduino15\packages\w80x_duino\hardware\XT804\0.0.5\cores\w806\lib\drivers
Instead of PB6, PB27 is used. This makes it more convenient to switch CS via HAL
PB6 does not map to PSRAM controller
image
image

__HAL_AFIO_REMAP_PSRAM_CS(GPIOB, GPIO_PIN_27);
or
__HAL_AFIO_REMAP_PSRAM_CS(GPIOB, GPIO_PIN_1);
In this case, set the opposite CS to HIGH

But the question arises... What happens inside the PSRAM chip during reinitialization? If the regeneration system turns off at this moment, all data will be lost.
It seems to me that it is enough to do the initialization once for each bank. And then just remap only CS to the required bank

@jcoleman-oneaihealth
Copy link
Author

jcoleman-oneaihealth commented Nov 12, 2023

Ok Thx ,
yeah only PB1 + PB27 as PSRAM_CS.
Let me try.

I also ordered :
SN74LVC138AD SN74LVC1G3157DCKR

I found the code.
Its the arduino code hidden in the users dir ...
There is a DeInit() function :

/**
  * @brief  Initializes the PSRAM according to the specified parameters
  *         in the PSRAM_InitTypeDef and create the associated handle.
  * @param  hpsram pointer to a PSRAM_HandleTypeDef structure that contains
  *         the configuration information for PSRAM module
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_PSRAM_Init(PSRAM_HandleTypeDef *hpsram)
{
	uint32_t value = 0x605;
	
	if(hpsram == NULL)
	{
		return HAL_ERROR;
	}
	assert_param(IS_PSRAM_INSTANCE(hpsram->Instance));
	assert_param(IS_PSRAM_DIV(hpsram->Init.Div));
	assert_param(IS_PSRAM_MODE(hpsram->Init.Mode));
	
	HAL_PSRAM_MspInit(hpsram);
	
	value |= ((hpsram->Init.Div << PSRAM_CR_DIV_Pos) | hpsram->Init.Mode);
	WRITE_REG(hpsram->Instance->CR, value);
	do{
		value = READ_REG(hpsram->Instance->CR);
	} while(value & 0x01);
	
	return HAL_OK;
}

/**
  * @brief  DeInitializes the PSRAM peripheral
  * @param  hpsram pointer to a PSRAM_HandleTypeDef structure that contains
  *         the configuration information for PSRAM module
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_PSRAM_DeInit(PSRAM_HandleTypeDef *hpsram)
{
	if (hpsram == NULL)
	{
		return HAL_ERROR;
	}
	
	assert_param(IS_PSRAM_INSTANCE(hpsram->Instance));
	HAL_PSRAM_MspDeInit(hpsram);
	
	return HAL_OK;
}

@AnatolSher
Copy link

jcoleman-oneaihealth
Hello! What progress has been made? You intrigued me with your idea with two psram chips. If I have free time next week, I'll try to do this in practice too. I don't know why I need this :)

@jcoleman-oneaihealth
Copy link
Author

jcoleman-oneaihealth commented Nov 15, 2023

It is useful.
I am working on Robotics AI, and Vision Recognition.

One of the projects is using the Ov7670 camera (from the Arduino Library) on the W806.
-- Multiple 8Mx8 PSRAMs would be very useful for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants