bthci/hci2implementations/initialisors/brcm/src/ControllerInitialisationPluginImpl.cpp
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//
/**
@file
@internalComponent
*/
#include <bluetooth/hcicommandQueue.h>
#include "broadcomcontrollerinitialisor.h"
#include "controllerinitialisationpluginimpl.h"
#include <bluetooth/hci/vendordebugcommand.h>
#include <bluetooth/hci/controllerinitialisationobserver.h>
#include <bluetooth/hci/commandcompleteevent.h>
#include <bluetooth/hci/vendordebugcompleteevent.h>
#include <bluetooth/hci/hctlinterface.h>
#include <bluetooth/hci/corehci.h>
#include <bluetooth/logger.h>
#include <e32debug.h>
#include <CIniData.h>
#define INITIALISOR_BCM_LOGGER
#define BCM_TRANSPORT
#define UPDATEBAUDRATE_AFTER_PRD
#ifdef INITIALISOR_BCM_LOGGER
#define INITIALISOR_BCM_LOG(A) RDebug::Print(A);
#define INITIALISOR_BCM_LOG2(A,B) RDebug::Print(A,B);
#define INITIALISOR_BCM_LOG3(A,B,C) RDebug::Print(A,B,C);
#else
#define INITIALISOR_BCM_LOG(A)
#define INITIALISOR_BCM_LOG2(A,B)
#define INITIALISOR_BCM_LOG3(A,B,C)
#define INITIALISOR_BCM_LOG4(A,B,C,D)
#endif
const TUint32 BCM2048_RAM_LOCATION = 0x00085D00;
const TUint32 BCM4325_RAM_LOCATION = 0x00086800;
const TUint32 BCM2046_RAM_LOCATION = 0x00086800 ; //0x00087AC8;
TUint32 KDestRamLocation = BCM2048_RAM_LOCATION; // by default this location is for BCM2048
// 50 mstimer.
const TInt KMiniDriverToPatchRamTimerDuration = 50000; // 50000;
const TInt KEndDelayTimerDuration = 750000; //250000;
#define BAUDRATE_921600 921600
#define BAUDRATE_115200 115200
#define BAUDRATE_57600 BAUDRATE_921600 // for now we map the BR 57600 to 921600
#define UART_24MHZ_CLOCK 24000000
TInt iBaudRate = BAUDRATE_115200; // default baudrate
TInt iBaudRateAfter = BAUDRATE_115200; // default baudrate
TInt iUartClock = UART_24MHZ_CLOCK; // default baudrate
#ifdef BCM_TRANSPORT
_LIT(KDefaultIniFileName, "hctl_broadcom.ini");
#else
_LIT(KDefaultIniFileName, "hctl_uart_original.ini");
#endif
_LIT(KConfigFileFileFormat, "%S%S");
#if 0
_LIT(KDefaultConfigFileFileFormat, "%S%S.bin");
#else
_LIT(KDefaultConfigFileFileFormat, "%S%S.hcd");
#endif
_LIT(KDefaultConfigFileName, "BCM2046B1");
_LIT(KDefaultConfigFilePath, "z:\\private\\101f7989\\Bluetooth\\");
_LIT(KGlobalReadySemName, "BCM_BT_READY_010155");
//RSemaphore BCM_DriverReadySem;
#ifdef __FLOG_ACTIVE
_LIT8(KLogComponent, LOG_COMPONENT_INITIALISOR_BROADCOM);
//_LIT8(KLogComponent, "InitBRCM");
#endif
/*static*/ CControllerInitialisationPluginImpl* CControllerInitialisationPluginImpl::NewL()
{
LOG_STATIC_FUNC
CControllerInitialisationPluginImpl* self = new (ELeave) CControllerInitialisationPluginImpl();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
CControllerInitialisationPluginImpl::~CControllerInitialisationPluginImpl()
{
LOG_FUNC
// Delete async CallBacks. If running, these should be cancelled by the
// d'tor of CAsyncOneShot.
delete iAsyncCallBackForPostReset;
delete iCConfigFileDownload;
delete iMiniDrive2ConfigFileTimer;
}
void CControllerInitialisationPluginImpl::ConstructL()
{
LOG_FUNC
// Add Async Callbacks
TCallBack postResetCallBack(AsyncCallBackForPostReset, this);
iAsyncCallBackForPostReset = new (ELeave)CAsyncCallBack(postResetCallBack, CActive::EPriorityStandard);
iMiniDrive2ConfigFileTimer = CConfigFileTimer::NewL(*this);
}
// Protected constructor.
CControllerInitialisationPluginImpl::CControllerInitialisationPluginImpl()
{
LOG_FUNC
}
/*virtual*/ void CControllerInitialisationPluginImpl::MciiPreResetCommand()
{
LOG_FUNC
__ASSERT_DEBUG(iControllerInitialisationObserver, PANIC(KBroadcomControllerInitialisorPanic, ENullInitialisationObserver));
// Do any pre-reset initialisation...
#ifndef __WINSCW__
INITIALISOR_BCM_LOG2(_L("Initialisor_Broadcom : Set Initial BaudRate to %d before reset"), iBaudRate)
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciUpdateBaudRate(iBaudRate);
#endif
INITIALISOR_BCM_LOG(_L("Initialisor_Broadcom : call McioPreResetCommandComplete(KErrNone)"))
// Inform stack that we have finished
iControllerInitialisationObserver->McioPreResetCommandComplete(KErrNone);
}
/*virtual*/ TAny* CControllerInitialisationPluginImpl::Interface(TUid aUid)
{
LOG_FUNC
TAny* ret = NULL;
switch(aUid.iUid)
{
case KControllerInitialisationInterfaceUid:
ret = reinterpret_cast<TAny*>(static_cast<MControllerInitialisationInterface*>(this));
break;
default:
break;
};
return ret;
}
/*static*/ TInt CControllerInitialisationPluginImpl::AsyncCallBackForPostReset(TAny* aInitPlugin)
{
LOG_STATIC_FUNC
INITIALISOR_BCM_LOG(_L("Initialisor_Broadcom : CControllerInitialisationPluginImpl::AsyncCallBackForPostReset(TAny* aInitPlugin)"))
CControllerInitialisationPluginImpl* initPlugin = static_cast<CControllerInitialisationPluginImpl*>(aInitPlugin);
initPlugin->DoPostReset();
return EFalse; // Don't call back any more.
}
void CControllerInitialisationPluginImpl::InitialiseAndLoadMiniDriver()
{
LOG_FUNC
CVendorDebugCommand* cmd = NULL;
TInt err = KErrNone;
INITIALISOR_BCM_LOG(_L("Initialisor_Broadcom : InitialiseAndLoadMiniDriver()"))
// Chinda - Check for specific patch ram file in patch_ram section in hctl_bcm.ini file
TFileName fileName;
CIniData* pIniFile = NULL;
TName name;
name.Copy(KDefaultConfigFilePath);
name.Append(KDefaultIniFileName);
_LIT(KFileHcdExtension,"*.hcd");
_LIT(KFileBinExtension,"*.bin");
_LIT(KPatchramSection, "patch_ram");
_LIT(KPatchramPath, "path");
_LIT(KPatchramFile, "file");
_LIT(KPatchramLocation, "location");
TInt iRamLocation;
TRAP(err, pIniFile = CIniData::NewL(name));
if (err != KErrNone)
{
// Attempt to open the config file.
fileName.Format(KDefaultConfigFileFileFormat,&KDefaultConfigFilePath, &KDefaultConfigFileName);
iBaudRate = BAUDRATE_115200;
iBaudRateAfter = BAUDRATE_115200;
}
else
{
// First read COM port and baudrate
if (pIniFile)
{
_LIT(KCOMPortSection, "hctl");
_LIT(KCOMBaudRate, "baud_rate");
_LIT(KCOMBaudRateAfter, "functional_baud_rate");
_LIT(KCOMUARTClock, "uart_clock");
if (!pIniFile->FindVar(KCOMPortSection, KCOMBaudRate, iBaudRate))
{
iBaudRate = BAUDRATE_115200;
}
if (!pIniFile->FindVar(KCOMPortSection, KCOMBaudRateAfter, iBaudRateAfter))
{
iBaudRateAfter = BAUDRATE_115200;
}
if (!pIniFile->FindVar(KCOMPortSection, KCOMUARTClock, iUartClock))
{
iUartClock = UART_24MHZ_CLOCK;
}
TPtrC PathText;
TPtrC FileText;
//TBufC8<256> strFileExtension;
if (!pIniFile->FindVar(KPatchramSection, KPatchramPath, PathText))
{
PathText.Set(KDefaultConfigFilePath);
}
#if 1
if (!pIniFile->FindVar(KPatchramSection, KPatchramFile, FileText))
{
FileText.Set(KDefaultConfigFileName);
fileName.Format(KDefaultConfigFileFileFormat,&PathText, &FileText);
}
else
{
fileName.Format(KConfigFileFileFormat,&PathText, &FileText);
}
}
else
{
//FileText.Set(KDefaultConfigFileName);
fileName.Format(KDefaultConfigFileFileFormat,&KDefaultConfigFilePath, &KDefaultConfigFileName);
// ADD EXTENSION CHECK HERE
}
// Check if we have an hcd file to download
if(fileName.Match(KFileHcdExtension) != KErrNotFound)
{
iFileFormat = EHcdFileFormat;
delete pIniFile;
}
else
{
// Check if we have a binary file to download
if(fileName.Match(KFileBinExtension) != KErrNotFound)
{
iFileFormat = EBinFileFormat;
// check for ram location in ini file
if (pIniFile->FindVar(KPatchramSection, KPatchramLocation, iRamLocation) != EFalse)
KDestRamLocation = iRamLocation;
else if (fileName.Find(_L("2048")) != KErrNotFound)
KDestRamLocation = BCM2048_RAM_LOCATION;
else if (fileName.Find(_L("4325")) != KErrNotFound)
KDestRamLocation = BCM4325_RAM_LOCATION;
else if (fileName.Find(_L("2046")) != KErrNotFound)
KDestRamLocation = BCM2046_RAM_LOCATION;
delete pIniFile;
}
else //Unknown file type SHOULD NEVER FALL IN THIS CONDITION
{
iInitState = EIdle;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EIdle);
iFileFormat = EUnknownFileFormat;
delete pIniFile;
return;
}
}
}
#else
if (!pIniFile->FindVar(KPatchramSection, KPatchramFile, FileText))
{
FileText.Set(KDefaultConfigFileName);
fileName.Format(KDefaultConfigFileFileFormat,&PathText, &FileText);
}
else
{
fileName.Format(KConfigFileFileFormat,&PathText, &FileText);
}
// check for ram location in ini file
if (pIniFile->FindVar(KPatchramSection, KPatchramLocation, iRamLocation) != EFalse)
KDestRamLocation = iRamLocation;
else if (fileName.Find(_L("2048")) != KErrNotFound)
KDestRamLocation = BCM2048_RAM_LOCATION;
else if (fileName.Find(_L("4325")) != KErrNotFound)
KDestRamLocation = BCM4325_RAM_LOCATION;
else if (fileName.Find(_L("2046")) != KErrNotFound)
KDestRamLocation = BCM2046_RAM_LOCATION;
delete pIniFile;
}
else
{
fileName.Format(KDefaultConfigFileFileFormat,&KDefaultConfigFilePath, &KDefaultConfigFileName);
}
}
#endif
// Open the config file
TRAP(err, iCConfigFileDownload = CConfigFileDownload::NewL(fileName));
if (err != KErrNone)
{
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
iInitState = EIdle;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EIdle);
}
else
{
// initiate Dwl config file
TRAP(err, cmd = CVendorDebugCommand::NewL(KHciVSDownloadMiniDriver));
if (err == KErrNone)
{
TRAP(err, iHCICommandQueue->MhcqAddInitCommandL(cmd, *this));
if(err != KErrNone)
{
// Inform the stack of the initialisation status.
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
iInitState = EIdle;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EIdle);
}
else
{
if(iFileFormat == EBinFileFormat)
{
iDestRam = KDestRamLocation;
iTxPatchLength = 0;
}
iInitState = EloadingMiniDriver;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EloadingMiniDriver);
}
}
else
{
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
iInitState = EIdle;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EIdle);
}
}
}
void CControllerInitialisationPluginImpl::DoPostReset()
{
LOG_FUNC
INITIALISOR_BCM_LOG(_L("Initialisor_Broadcom : CControllerInitialisationPluginImpl::DoPostReset()"))
InitialiseAndLoadMiniDriver();
}
/*virtual*/ void CControllerInitialisationPluginImpl::MciiPostResetCommand()
{
LOG_FUNC
__ASSERT_DEBUG(iControllerInitialisationObserver, PANIC(KBroadcomControllerInitialisorPanic, ENullInitialisationObserver));
// Use async callback
iAsyncCallBackForPostReset->CallBack();
}
void CControllerInitialisationPluginImpl::HandleVendorSpecificCompleteEvent(const TVendorDebugCompleteEvent& aEvent)
{
LOG_FUNC
CVendorDebugCommand* cmd = NULL;
TInt err = KErrNone;
THCIErrorCode hcierr = EOK;
switch(iInitState)
{
case EloadingMiniDriver:
{
if (aEvent.CommandOpcode() == KHciVSDownloadMiniDriver )
{
INITIALISOR_BCM_LOG2(_L("Initialisor_Broadcom : HCI VSC Download Mini Driver event (%04x)"), aEvent.CommandOpcode())
hcierr = aEvent.ErrorCode();
if (hcierr == EOK)
{
// Delay before actual patch ram download
iMiniDrive2ConfigFileTimer->Start(KMiniDriverToPatchRamTimerDuration);
if(iFileFormat == EBinFileFormat)
{
iInitState = EMiniDrvToBinConfigFileDelay;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EMiniDrvToBinConfigFileDelay);
}
else if(iFileFormat == EHcdFileFormat)
{
iInitState = EMiniDrvToHcdConfigFileDelay;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EMiniDrvToHcdConfigFileDelay);
}
}
}
}
break;
case ELoadingHcdConfigFileData:
{
INITIALISOR_BCM_LOG(_L("WRITE RAM COMPLETE EVENT"))
if (aEvent.CommandOpcode() == KHciVSWriteRam )
{
hcierr = aEvent.ErrorCode();
if (hcierr == EOK)
{
THCIOpcode CommandOpcode;
TUint8 DataChunkLen = 0;
iCConfigFileDownload->ReadCommandOpcode(CommandOpcode);
TRAP(err, cmd = CVendorDebugCommand::NewL(CommandOpcode));
if (err == KErrNone)
{
TDes8& cmdData = cmd->Command();
iCConfigFileDownload->ReadDataChunkLen(DataChunkLen);
if(DataChunkLen != 0)
{
TBuf8<4> AddressBuf;
TBuf8<KHcdConfigFileChunkSize> patchRamData;
if(CommandOpcode == KHciVSLaunchRam)
{
err = iCConfigFileDownload->ConfigFileSendData(patchRamData,DataChunkLen);
if (KErrNone == err)
{
cmd->Reset(KHciVSLaunchRam);
cmdData.Append(patchRamData);
INITIALISOR_BCM_LOG(_L("LAUNCH RAM"))
iInitState = ELoadingconfigFileDataDone;
TRAP(err, iHCICommandQueue->MhcqAddInitCommandL(cmd, *this));
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(ELoadingconfigFileDataDone);
}
}
else
{
err = iCConfigFileDownload->SetDataChunkAddress(AddressBuf);
if (KErrNone == err)
{
cmdData.FillZ(4);
cmdData[0] = AddressBuf[0];
cmdData[1] = AddressBuf[1];
cmdData[2] = AddressBuf[2];
cmdData[3] = AddressBuf[3];
err = iCConfigFileDownload->ConfigFileSendData(patchRamData,(DataChunkLen-4));
if (KErrNone == err)
{
cmdData.Append(patchRamData);
TRAP(err, iHCICommandQueue->MhcqAddInitCommandL(cmd, *this));
INITIALISOR_BCM_LOG(_L("WRITE RAM"))
}
}
}
}
}
if(KErrNone != err)
{
// something went wrong during the file read
delete cmd; //command was not sent due to read file error
// Inform the stack of the initialisation status.
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
iInitState = EIdle;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EIdle);
}
}//hcierr == EOK
}//aEvent.CommandOpcode() == KHciVSWriteRam
else
{
err = KErrGeneral; //complete event is not the expected one
}
}
break;
case ELoadingBinConfigFileData:
{
if (aEvent.CommandOpcode() == KHciVSWriteRam )
{
hcierr = aEvent.ErrorCode();
if (hcierr == EOK)
{
//Update the Destination Ram address
iDestRam = iDestRam + iTxPatchLength;
TRAP(err, cmd = CVendorDebugCommand::NewL(KHciVSWriteRam));
if (err == KErrNone)
{
TBuf8<KConfigFileChunkSize> patchRamData;
// Try to read config file data
err = iCConfigFileDownload->ConfigFileSendDataChunk(patchRamData);
if (KErrEof == err)
{
// EOF reached
iInitState = ELoadingconfigFileDataDone;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(ELoadingconfigFileDataDone);
// Launch Patch ram
cmd->Reset(KHciVSLaunchRam);
// reuse allocated cmd
TDes8& cmdData = cmd->Command();
cmdData.FillZ(4);
cmdData[0] = 0xFF;
cmdData[1] = 0xFF;
cmdData[2] = 0xFF;
cmdData[3] = 0xFF;
TRAP(err, iHCICommandQueue->MhcqAddInitCommandL(cmd, *this));
// Wait for the launch config file complete event
}
else if (KErrNone == err)
{
TDes8& cmdData = cmd->Command();
INITIALISOR_BCM_LOG2(_L("Initialisor_Broadcom : HCI VSC Write RAM event (%04x)"), aEvent.CommandOpcode())
cmdData.FillZ(4);
cmdData[0] = (iDestRam) & 0xFF;
cmdData[1] = ((iDestRam) >> 8) & 0xFF;
cmdData[2] = ((iDestRam) >> 16) & 0xFF;
cmdData[3] = ((iDestRam) >> 24) & 0xFF;
cmdData.Append(patchRamData);
// Send another chunk of config file data
TRAP(err, iHCICommandQueue->MhcqAddInitCommandL(cmd, *this));
if (KErrNone == err)
{
// Update length of Tx'd data
iTxPatchLength = patchRamData.Length();
iInitState = ELoadingBinConfigFileData;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(ELoadingBinConfigFileData);
// Wait for the VSC complete event
}
}
else if (KErrNone != err)
{
// something went wrong during the file read
delete cmd; //command was not sent due to read file error
}
}
}
else
{
err = KErrGeneral; //complete event is not the expected one
}
if (err != KErrNone)
{
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
iInitState = EIdle;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EIdle);
}
}
}
break;
case ELoadingconfigFileDataDone:
{
INITIALISOR_BCM_LOG(_L("LAUNCH RAM COMPLETE EVENT"))
if (aEvent.CommandOpcode() == KHciVSLaunchRam)
{
INITIALISOR_BCM_LOG2(_L("Initialisor_Broadcom : HCI VSC Launch RAM event (%04x)"), aEvent.CommandOpcode())
hcierr = aEvent.ErrorCode();
if (hcierr == EOK)
{
iMiniDrive2ConfigFileTimer->Start(KEndDelayTimerDuration);
iInitState = EWaitEndDelay;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EWaitEndDelay);
}
}
}
break;
case EWaitUpdateBaudRateAfterPrm:
{
#ifdef UPDATEBAUDRATE_AFTER_PRD
INITIALISOR_BCM_LOG2(_L("Initialisor_Broadcom : VSC Update BaudRate event (%04x)"), aEvent.CommandOpcode())
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
if (aEvent.CommandOpcode() == KHciVSUpdateUartHCIBaudRate)
{
hcierr = aEvent.ErrorCode();
if (hcierr == EOK)
{
INITIALISOR_BCM_LOG2(_L("Initialisor_Broadcom : Change UART BaudRate to %d bps after launching RAM"), iBaudRateAfter)
err = hctlConfigInterface->MhciUpdateBaudRate(iBaudRateAfter);
}
else
{
err = KErrGeneral;
}
}
else
{
err = KErrGeneral;
}
#else
err = KErrNone;
#endif
// BCM initialisation is completed- resume generic init
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
iInitState = EIdle;
hctlConfigInterface->MhciSetInitPluginState(EIdle);
//iInitState = EReset;
// Signal to everyone that we are ready
//BCM_DriverReadySem.CreateGlobal(KGlobalReadySemName,1,EOwnerProcess);
}
break;
default:
INITIALISOR_BCM_LOG2(_L("Broadcom: CControllerInitialisationPluginImpl::HandleVendorSpecificCompleteEvent - Default state (%d)"),iInitState)
break;
}
}
/*virtual*/ void CControllerInitialisationPluginImpl::ConfigFileTimerExpired()
{
LOG_FUNC
TInt err = KErrNone;
CVendorDebugCommand* cmd = NULL;
switch(iInitState)
{
case EMiniDrvToHcdConfigFileDelay:
{
THCIOpcode CommandOpcode;
TUint8 DataChunkLen = 0;
INITIALISOR_BCM_LOG(_L("Initialisor_Broadcom : Start patch ram download"))
iCConfigFileDownload->ReadCommandOpcode(CommandOpcode);
TRAP(err, cmd = CVendorDebugCommand::NewL(CommandOpcode));
TDes8& cmdData = cmd->Command();
iCConfigFileDownload->ReadDataChunkLen(DataChunkLen);
if(DataChunkLen != 0)
{
//TBuf8<4> AddressBuf;
TBuf8<4> AddressBuf;
err = iCConfigFileDownload->SetDataChunkAddress(AddressBuf);
if (KErrNone == err)
{
cmdData.FillZ(4);
cmdData[0] = AddressBuf[0];
cmdData[1] = AddressBuf[1];
cmdData[2] = AddressBuf[2];
cmdData[3] = AddressBuf[3];
TBuf8<KHcdConfigFileChunkSize> HcdpatchRamData;
// Substract 4 from DataChunkLen for download address
err = iCConfigFileDownload->ConfigFileSendData(HcdpatchRamData,(DataChunkLen-4));
if (KErrNone == err)
{
cmdData.Append(HcdpatchRamData);
TRAP(err, iHCICommandQueue->MhcqAddInitCommandL(cmd, *this));
INITIALISOR_BCM_LOG(_L("FIRST WRITE RAM"))
if (KErrNone == err)
{
iInitState = ELoadingHcdConfigFileData;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(ELoadingHcdConfigFileData);
}
}
}
if(KErrNone != err)
{
// something went wrong during the file read
delete cmd; //command was not sent due to read file error
// Inform the stack of the initialisation status.
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
iInitState = EIdle;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EIdle);
}
}
}
break;
case EMiniDrvToBinConfigFileDelay:
{
INITIALISOR_BCM_LOG(_L("Initialisor_Broadcom : Waiting for Mini download Driver"))
// initiate actual downloading of the Config file
TRAP(err, cmd = CVendorDebugCommand::NewL(KHciVSWriteRam));
if (err == KErrNone)
{
TBuf8<KConfigFileChunkSize> patchRamData;
TDes8& cmdData = cmd->Command();
err = iCConfigFileDownload->ConfigFileSendDataChunk(patchRamData);
// Start sending config file data
if (KErrNone == err)
{
cmdData.FillZ(4);
cmdData[0] = (KDestRamLocation) & 0xFF;
cmdData[1] = ((KDestRamLocation) >> 8) & 0xFF;
cmdData[2] = ((KDestRamLocation) >> 16) & 0xFF;
cmdData[3] = ((KDestRamLocation) >> 24) & 0xFF;
cmdData.Append(patchRamData);
TRAP(err, iHCICommandQueue->MhcqAddInitCommandL(cmd, *this));
if (KErrNone == err)
{
// Update length of Tx'd data
iTxPatchLength = iTxPatchLength + patchRamData.Length();
iInitState = ELoadingBinConfigFileData;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(ELoadingBinConfigFileData);
// Wait for the VSC complete event
}
}
else
{
// something went wrong during the file read
delete cmd; //command was not sent due to read file error
}
}
if (KErrNone != err)
{
// Inform the stack of the initialisation status.
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
iInitState = EIdle;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EIdle);
}
}
break;
case EWaitEndDelay:
{
#ifdef UPDATEBAUDRATE_AFTER_PRD
// BCM initialisation is completed- resume generic init
INITIALISOR_BCM_LOG(_L("Initialisor_Broadcom : END Initialisation steps (PatchRAM downloaded OK))"))
// Request baud rate update.
CVendorDebugCommand* cmd = NULL;
TRAP(err, cmd = CVendorDebugCommand::NewL(KHciVSUpdateUartHCIBaudRate));
TDes8& cmdData = cmd->Command();
if(err == KErrNone)
{
INITIALISOR_BCM_LOG2(_L("Initialisor_Broadcom : Change BaudRate to %d bps after launchRAM"), iBaudRateAfter)
INITIALISOR_BCM_LOG2(_L("Initialisor_Broadcom : UART Clock is %d"), iUartClock)
cmdData.FillZ(6);
cmdData[2] = iBaudRateAfter & 0xFF;
cmdData[3] = (iBaudRateAfter >> 8) & 0xFF;
cmdData[4] = (iBaudRateAfter >> 16) & 0xFF;
cmdData[5] = (iBaudRateAfter >> 24) & 0xFF;
TRAP(err, iHCICommandQueue->MhcqAddInitCommandL(cmd, *this));
// error handling if the method above fails is handled in at the end of the function
// INITIALISOR_BCM_LOG2(_L("Initialisor_Broadcom : Send %x %x %x %x %x %x after launchRAM OK"), iBaudRateAfter)
RDebug::Print(_L("Initialisor_Broadcom : Send %x %x %x %x %x %x after launchRAM OK"),
cmdData[0],
cmdData[1],
cmdData[2],
cmdData[3],
cmdData[4],
cmdData[5]);
iInitState = EWaitUpdateBaudRateAfterPrm;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EWaitUpdateBaudRateAfterPrm);
}
#else
iInitState = EWaitUpdateBaudRateAfterPrm;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EWaitUpdateBaudRateAfterPrm);
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
#endif
if(err != KErrNone)
{
iInitState = EIdle;
MHctlBcmConfigInterface* hctlConfigInterface = static_cast<MHctlBcmConfigInterface*>(iCoreHci->MchHctlPluginInterface(TUid::Uid(KHctlBcmConfigInterfaceUid)));
__ASSERT_DEBUG(hctlConfigInterface, PANIC(KBroadcomControllerInitialisorPanic, EConfigInterfaceNull));
hctlConfigInterface->MhciSetInitPluginState(EIdle);
iControllerInitialisationObserver->McioPostResetCommandComplete(err);
}
// Signal to everyone that we are ready
//BCM_DriverReadySem.CreateGlobal(KGlobalReadySemName,1,EOwnerProcess);
}
break;
default:
break;
}
}
/*virtual*/ void CControllerInitialisationPluginImpl::MciiSetHCICommandQueue(MHCICommandQueue& aHCICommandQueue)
{
LOG_FUNC
__ASSERT_DEBUG(iHCICommandQueue == 0, PANIC(KBroadcomControllerInitialisorPanic, EHciCommandQueueOverwritten));
iHCICommandQueue = &aHCICommandQueue;
}
/*virtual*/ void CControllerInitialisationPluginImpl::MciiSetControllerInitialisationObserver(MControllerInitialisationObserver& aObserver)
{
LOG_FUNC
__ASSERT_DEBUG(iControllerInitialisationObserver == 0, PANIC(KBroadcomControllerInitialisorPanic, EInitialisationObserverOverwritten));
iControllerInitialisationObserver = &aObserver;
}
void CControllerInitialisationPluginImpl::MhcqcCommandErrored(TInt aErrorCode,
const CHCICommandBase* /*aCommand*/)
{
LOG_FUNC
switch(iInitState)
{
default:
PANIC(KBroadcomControllerInitialisorPanic, EInvalidInitialisorState);
break;
};
}
void CControllerInitialisationPluginImpl::MhcqcCommandEventReceived(const THCIEventBase& aEvent,
const CHCICommandBase* /*aRelatedCommand*/)
{
LOG_FUNC
if (aEvent.EventCode() == ECommandCompleteEvent)
{
// Switch on the opcode.
THCICommandCompleteEvent& event = THCICommandCompleteEvent::Cast(aEvent);
switch(event.CommandOpcode())
{
default:
// Check for VS commands.
if((event.CommandOpcode() & KVendorDebugOGF) == KVendorDebugOGF)
{
TVendorDebugCompleteEvent& vEvent = TVendorDebugCompleteEvent::Cast(event);
HandleVendorSpecificCompleteEvent(vEvent);
}
break;
}
}
}
/*virtual*/ void CControllerInitialisationPluginImpl::MciiSetCoreHci(MCoreHci& aCoreHci)
{
LOG_FUNC
INITIALISOR_BCM_LOG(_L("Initialisor_Broadcom : Setting Core HCI"))
__ASSERT_DEBUG(iCoreHci == 0, PANIC(KBroadcomControllerInitialisorPanic, ECoreHciOverwritten));
iCoreHci = &aCoreHci;
}