Part Number: AM5708
Other Parts Discussed in Thread: DM385
Hi,
I need to start CAMSS module of AM5708 under RTOS. I took as a base of Linux driver for CSI2_PHY. I can't understand what I should do flag RESET_DONE set in register CAL_CSI2_COMPLEXIO_CFG_0 .
For the first I configure module CSI2_PHY
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
HW_WR_REG32(0x4845B330, 0x00000001); // CAL_CSI2_CTX0_0
// DT DT type: MIPI CSI-2 Specs
// 0x1: All - DT filter is disabled
// 0x24: RGB888 1 pixel = 3 bytes
// 0x2B: RAW10 4 pixels = 5 bytes
// 0x2A: RAW8 1 pixel = 1 byte
// 0x1E: YUV422 2 pixels = 4 bytes
// VC (Virtual Channel) is 0
// NUM_LINES_PER_FRAME => 0 means auto detect
HW_WR_REG32(0x4845B304, 0x00000123); // CAL_CSI2_COMPLEXIO_CFG_0
// Clock - pos 3
// Data[0] - pos 2
// Data[1] - pos 1
// Enable IRQ_WDMA_END 0 / 1
HW_WR_REG32(0x4845B028 + 0x10, 0x00000001); // CAL_HL_IRQENABLE_SET_1
// Enable IRQ_WDMA_START 0 / 1
HW_WR_REG32(0x4845B028 + 0x20, 0x00000001); // CAL_HL_IRQENABLE_SET_1
// Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling
HW_WR_REG32(0x4845B318, 0xFF000000); // CAL_CSI2_VC_IRQENABLE_0
/* Steps
* 1. Configure D-PHY mode and enable required lanes
* 2. Reset complex IO - Wait for completion of reset
* Note if the external sensor is not sending byte clock,
* the reset will timeout
* 3 Program Stop States
* A. Program THS_TERM, THS_SETTLE, etc... Timings parameters
* in terms of DDR clock periods
* B. Enable stop state transition timeouts
* 4.Force FORCERXMODE
* D. Enable pull down using pad control
* E. Power up PHY
* F. Wait for power up completion
* G. Wait for all enabled lane to reach stop state
* H. Disable pull down using pad control
*/
/* 1. Configure D-PHY mode and enable required lanes */
HW_WR_REG32(0x4A002E94, 0x00026400); // CTRL_CORE_CAMERRX_CONTROL
// CSI_CTRLCLKEN = 1
// CSI0_CAMMODE = 0 (DPHY mode)
// CSI0_LANEENABLE = 3 (2 lanes enable)
// CSI0_MODE = 1
UARTConfigPrintf(DEBUG_UART_BASE, "CTRL_CORE_CAMERRX_CONTROL(0x4A002E94): %08X\n", HW_RD_REG32(0x4A002E94));
/* 2. Reset complex IO - Do not wait for reset completion */
dwTmp = HW_RD_REG32(0x4845B304);
HW_WR_REG32(0x4845B304, dwTmp | 0x40000000); // CAL_CSI2_COMPLEXIO_CFG_0
// RESET_CTRL = 1 (Complex IO reset de-asserted)
dwTmp = HW_RD_REG32(0x4845B304); // Dummy read to allow SCP to complete
UARTConfigPrintf(DEBUG_UART_BASE, "CAL_CSI2_COMPLEXIO_CFG_0(0x4845B304): %08X\n", dwTmp);
/* 3.A. Program Phy Timing Parameters */
//UARTConfigPrintf(DEBUG_UART_BASE, "REG0(0x4845B800): %08X\n", HW_RD_REG32(0x4845B800));
HW_WR_REG32(0x4845B800, 0x01000427); // THS_SETTLE = 0x27 (for 400 MHz) Programmed value = floor(105 ns/DDRClk period) + 4
// THS_TERM = 0x04 (for 400 MHz) Programmed value = floor(20 ns/DDRClk period)
// HSCLOCKCONFIG = 1 (Disable clock missing detector)
UARTConfigPrintf(DEBUG_UART_BASE, "REG0(0x4845B800): %08X\n", HW_RD_REG32(0x4845B800));
//UARTConfigPrintf(DEBUG_UART_BASE, "REG1(0x4845B804): %08X\n", HW_RD_REG32(0x4845B804));
HW_WR_REG32(0x4845B804, 0x0002E10E); // Default Value
UARTConfigPrintf(DEBUG_UART_BASE, "REG1(0x4845B804): %08X\n", HW_RD_REG32(0x4845B804));
/* 3.B. Program Stop States */
HW_WR_REG32(0x4845B314, 0x00004197); // CAL_CSI2_TIMING_0
// STOP_STATE_COUNTER_IO1 = 0x197
// STOP_STATE_X4_IO1 = 0
// STOP_STATE_X16_IO1 = 1
UARTConfigPrintf(DEBUG_UART_BASE, "CAL_CSI2_TIMING_0 (0x4845B314): %08X\n", HW_RD_REG32(0x4845B314));
/* 4. Force FORCERXMODE */
dwTmp = HW_RD_REG32(0x4845B314);
dwTmp |= 0x00008000;
HW_WR_REG32(0x4845B314, dwTmp);
UARTConfigPrintf(DEBUG_UART_BASE, "CAL_CSI2_TIMING_0 (0x4845B314): %08X\n", HW_RD_REG32(0x4845B314));
/* E. Power up the PHY using the complex IO */
dwTmp = HW_RD_REG32(0x4845B304);
dwTmp |= 0x08000000; // PWR_CMD = 1
HW_WR_REG32(0x4845B304, dwTmp);
UARTConfigPrintf(DEBUG_UART_BASE, "CAL_CSI2_COMPLEXIO_CFG_0 (0x4845B304): %08X\n", HW_RD_REG32(0x4845B304));
/* F. Wait for power up completion */
for(dwTmp = 0;dwTmp < 10;dwTmp++)
{
if((HW_RD_REG32(0x4845B304) & 0x02000000) != 0)
break; // Waiting for Power On
Osal_delay(1);
}
if(dwTmp < 10)
UARTConfigPuts(DEBUG_UART_BASE, "CSI-2 Powered Up\n", -1);
else
UARTConfigPuts(DEBUG_UART_BASE, "CSI-2 timeout\n", -1);
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
As a result CSI-2 powered up well. Then I start up the CSI2 source (1080p) and waiting for flag RESET_DONE.
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
/* 2. Wait for reset completion */
for (dwTmp = 0; dwTmp < 250; dwTmp++)
{
dwReg = HW_RD_REG32(0x4845B304);
if((dwReg & 0x20000000) != 0) // CAL_CSI2_COMPLEXIO_CFG_0 (RESET_DONE bit)
break;
Osal_delay(1);
}
if(dwTmp < 250)
UARTConfigPuts(DEBUG_UART_BASE, "CSI-2 Complex IO Reset Done\n", -1);
else
UARTConfigPuts(DEBUG_UART_BASE, "CSI-2 Reset timeout\n", -1);
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
But flag doesn't set. Is this the problem with a signal or it's wrong initialization sequence?
Thank you for your help in advance!
Regards, Andrei