UINT16 AD7466_Driver::Read( INT32 Channel )
{
    AD7466_CONFIG* Config = &g_AD7466_Config;

    UINT16 ADC_Value;
    UINT16 Write16;

    // select the NO3 on MAX4704
    CPU_GPIO_SetPinState( Config->ADMUX_A0_GPIO_PIN, Config->ADMUX_Address[Channel].A0 );
    CPU_GPIO_SetPinState( Config->ADMUX_A1_GPIO_PIN, Config->ADMUX_Address[Channel].A1 );

    // data that is written is ignored, but reduce energy by keeping output high
    Write16 = 0xffff;

    CPU_GPIO_SetPinState( Config->ADMUX_EN_L_GPIO_PIN, FALSE );    // bring enable active (low)

    // delay 5 uSecs per RAY after enabling MUX to allow inrush current to settle and voltage to stabilize
    HAL_Time_Sleep_MicroSeconds_InterruptEnabled( 5 );

    {
        // we must ensure a radio operation ISR doesn't intervene - keep this short!
        GLOBAL_LOCK(irq);

        // W
        // R
        CPU_SPI_Xaction_Start( Config->SPI_Config );

        {
            SPI_XACTION_16 Transaction;

            Transaction.Read16          = &ADC_Value;
            Transaction.ReadCount       = 1;
            Transaction.ReadStartOffset = 1-1;
            Transaction.Write16         = &Write16;
            Transaction.WriteCount      = 1;

            CPU_SPI_Xaction_nWrite16_nRead16( Transaction );
        }

        CPU_SPI_Xaction_Stop( Config->SPI_Config );
    }

    CPU_GPIO_SetPinState( Config->ADMUX_EN_L_GPIO_PIN, TRUE );    // bring enable inactive (high)

    // scale down by 1 bit, since this is how it returns the result
    ADC_Value >>= 1;

    return ADC_Value;
}
Пример #2
0
BOOL LPC24XX_SPI_Driver::Xaction_Stop( const SPI_CONFIGURATION& Configuration )
{
    if(g_LPC24XX_SPI_Driver.m_Enabled[Configuration.SPI_mod])
    {        
        if(Configuration.CS_Hold_uSecs)
        {
            HAL_Time_Sleep_MicroSeconds_InterruptEnabled( Configuration.CS_Hold_uSecs );
        }
      
        // next, bring the CS to the proper inactive state
        if(Configuration.DeviceCS != LPC24XX_GPIO::c_Pin_None)
        {
            CPU_GPIO_SetPinState( Configuration.DeviceCS, !Configuration.CS_Active );
        }

        g_LPC24XX_SPI_Driver.m_Enabled[Configuration.SPI_mod] = FALSE;
    }
    else
    {
        lcd_printf("\fSPI Collision 4\r\n");
        HARD_BREAKPOINT();

        return FALSE;
    }

    return TRUE;
}
Пример #3
0
void USBH_ISR (void* param){
	GLOBAL_LOCK(irq);
	CPU_GPIO_SetPinState(18, 1);

	OTG_TypeDef* OTG = (OTG_TypeDef*)param;
	if (OTG->HPRT & OTG_HPRT_PCDET) {
		//device detected
		//clear bit
		OTG->HPRT |= OTG_HPRT_PCDET;
	}
}
Пример #4
0
// ---------------------------------------------------------------------------
void CPU_GPIO_EnableOutputPin(GPIO_PIN Pin, BOOL InitialState)
{
    LPC_GPIO_T *port_reg = (LPC_GPIO_T *) (LPC_GPIO_PORT_BASE);
    UINT8 port = LPC43XX_GPIO_PORT(Pin), bit = LPC43XX_GPIO_PIN(Pin);
    int f = 0;

    // Configure pin properties
    f = SCU_PINIO_FAST | ((port > 4) ? (4) : (0));
    PIN_Config(Pin, f);
    PIN_Mode(Pin, PullNone);
    port_reg->DIR[port] |= (1 << bit); // Output

    CPU_GPIO_SetPinState(Pin, InitialState);
}
BOOL __section(SectionForFlashOperations) AM29DL_32_BS_Driver::ChipReadOnly(void* context, BOOL On, UINT32 ProtectionKey )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();
    
    MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context;

    if(ProtectionKey != FLASH_PROTECTION_KEY) { ASSERT(0); return FALSE; }

    config->ChipProtection = On ? 0 : ProtectionKey;

    CPU_EBIU_Memory_ReadOnly( config->Memory, On );

    if(config->BlockConfig.WriteProtectionPin.Pin != GPIO_PIN_NONE)
    {
        CPU_GPIO_SetPinState( config->BlockConfig.WriteProtectionPin.Pin, On ? config->BlockConfig.WriteProtectionPin.ActiveState: !config->BlockConfig.WriteProtectionPin.ActiveState );

    }

    return TRUE;
}
Пример #6
0
BOOL CPU_SPI_Xaction_Stop(const SPI_CONFIGURATION& Configuration)
{
    LPC_SSP_T *spi = SPI_REG(Configuration.SPI_mod);
    while (SPI_Busy(spi)); // wait for completion

    if(Configuration.CS_Hold_uSecs)
    {
        HAL_Time_Sleep_MicroSeconds_InterruptEnabled(Configuration.CS_Hold_uSecs);
    }
    CPU_GPIO_SetPinState(Configuration.DeviceCS, !Configuration.CS_Active);
    GPIO_RESISTOR res = RESISTOR_PULLDOWN;
    if (Configuration.MSK_IDLE) res = RESISTOR_PULLUP;
    GPIO_PIN msk, miso, mosi;
    CPU_SPI_GetPins(Configuration.SPI_mod, msk, miso, mosi);
    CPU_GPIO_EnableInputPin(msk,  FALSE, NULL, GPIO_INT_NONE, res);
    CPU_GPIO_EnableInputPin(miso, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLDOWN);
    CPU_GPIO_EnableInputPin(mosi, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLDOWN);

    SPI_Disable(spi); // Disable SPI
    return TRUE;
}
BOOL  __section("SectionForFlashOperations")I28F_16_BS_Driver::ChipReadOnly( void* context, BOOL On, UINT32 ProtectionKey )
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();

    MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context;
    
    if(ProtectionKey != FLASH_PROTECTION_KEY) { ASSERT(0); return FALSE; }

    config->ChipProtection = On ? 0 : ProtectionKey;

    CPU_EBIU_Memory_ReadOnly( config->Memory, On );

    if(config->BlockConfig.WriteProtectionPin.Pin != GPIO_PIN_NONE)
    {
        CPU_GPIO_SetPinState( config->BlockConfig.WriteProtectionPin.Pin, On ? config->BlockConfig.WriteProtectionPin.ActiveState: !config->BlockConfig.WriteProtectionPin.ActiveState );

        // we need 200nS setup on FLASH_WP_L
        CYCLE_DELAY_LOOP( 6 );   // 5.52 clock cycles @ 27.6 clocks/uSec
    }

    return TRUE;
}
Пример #8
0
BOOL MC9328MXL_SPI_Driver::Xaction_Stop( const SPI_CONFIGURATION& Configuration )
{
    NATIVE_PROFILE_HAL_PROCESSOR_SPI();
    if(g_MC9328MXL_SPI_Driver.m_Enabled[Configuration.SPI_mod])
    {
        UINT32 index = Configuration.SPI_mod;

        MC9328MXL_SPI & SPI = MC9328MXL::SPI(index);

        // we should have cleared the last TBF on the last RBF true setting
        // we should never bring CS inactive with the shifter busy
        ASSERT( SPI.TransmitBufferEmpty());
        ASSERT( SPI.ReceiveBufferEmpty ());
        ASSERT( SPI.ShiftBufferEmpty   ());

        if(Configuration.CS_Hold_uSecs)
        {
            HAL_Time_Sleep_MicroSeconds_InterruptEnabled( Configuration.CS_Hold_uSecs );
        }



        // avoid noise drawing excess power on a floating line by putting this in pulldown
#if defined(PLATFORM_ARM_MC9328MXS)
        CPU_GPIO_EnableInputPin( MC9328MXL_SPI::c_SPI1_MISO, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLUP );
#else
        if (index == MC9328MXL_SPI::c_SPI1)
        {
            CPU_GPIO_EnableInputPin( MC9328MXL_SPI::c_SPI1_MISO, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLUP );
        }
        else
        {
            CPU_GPIO_EnableInputPin( MC9328MXL_SPI::c_SPI2_MISO, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLUP );
        }
#endif

        // next, bring the CS to the proper inactive state
        if((Configuration.DeviceCS != MC9328MXL_GPIO::c_Pin_None) && (Configuration.DeviceCS != MC9328MXL_SPI::c_SPI1_SS))
        {
            CPU_GPIO_SetPinState( Configuration.DeviceCS, !Configuration.CS_Active );
        }

        // make sure that we don't trigger the SS pin for LCD on the iMXS board, this may change if Freescale change their circuitry
        // can remove if not use on imxs platform
        // be safe, as LCD SPI access will use this function as well, set it back to Output
#if (HARDWARE_BOARD_TYPE >= HARDWARE_BOARD_i_MXS_DEMO_REV_V1_2)
        CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_SS, TRUE );

#endif

        // put pins in output low state when not in use to avoid noise since clock stop and reset will cause these to become inputs
#if defined(PLATFORM_ARM_MC9328MXS)
        CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_SCLK, FALSE );
        CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_MOSI, FALSE );
#else
        if (index == MC9328MXL_SPI::c_SPI1)
        {
            CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_SCLK, FALSE );
            CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI1_MOSI, FALSE );
        }
        else
        {
            CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI2_SCLK, FALSE );
            CPU_GPIO_EnableOutputPin( MC9328MXL_SPI::c_SPI2_MOSI, FALSE );
        }
#endif

        // off SPI module
        SPI.CONTROLREG &=  ~SPI.CONTROLREG_SPIEN;

        g_MC9328MXL_SPI_Driver.m_Enabled[Configuration.SPI_mod] = FALSE;
    }
    else
    {
        lcd_printf("\fSPI Collision 4\r\n");
        HARD_BREAKPOINT();

        return FALSE;
    }

    return TRUE;
}
Пример #9
0
//Initialize USB Host
// USB OTG Full Speed is controller 0
// USB OTG High Speed is controller 1
BOOL USBH_Initialize( int Controller ) {
	CPU_GPIO_EnableOutputPin(16+2, TRUE);
	// enable USB clock
	OTG_TypeDef* OTG;
	if (Controller == 0) {
		RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
		OTG = OTG_FS;
	}
	else if (Controller == 1) {
		RCC->AHB1ENR |= RCC_AHB1ENR_OTGHSEN;
		OTG = OTG_HS;
	}
	else {
		return FALSE;
	}
	//disable int
	OTG->GAHBCFG &= ~OTG_GAHBCFG_GINTMSK;

	//core init 1
	OTG->GINTSTS |= OTG_GINTSTS_RXFLVL;
	OTG->GAHBCFG |= OTG_GAHBCFG_PTXFELVL;
	//core init 2
	OTG->GUSBCFG &= ~OTG_GUSBCFG_HNPCAP;
	OTG->GUSBCFG &= ~OTG_GUSBCFG_SRPCAP;
	OTG->GUSBCFG &= ~OTG_GUSBCFG_TRDT;
	OTG->GUSBCFG |= STM32F4_USB_TRDT<<10;
	OTG->GUSBCFG |= OTG_GUSBCFG_PHYSEL;
	//core init 3
	OTG->GINTMSK |= OTG_GINTMSK_OTGINT | OTG_GINTMSK_MMISM;
	//force host mode
	OTG->GUSBCFG |= OTG_GUSBCFG_FHMOD;
	//host init
	OTG->GINTMSK |= OTG_GINTMSK_PRTIM;
	OTG->HCFG = OTG_HCFG_FSLSPCS_48MHZ;
	OTG->HPRT |= OTG_HPRT_PPWR;

	OTG->GCCFG |= (OTG_GCCFG_VBUSBSEN | OTG_GCCFG_VBUSASEN | OTG_GCCFG_NOVBUSSENS | OTG_GCCFG_PWRDWN);
	//
	//config pins and ISR
	if (Controller == 0) {
		CPU_GPIO_DisablePin(10, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)0xA2);
		CPU_GPIO_DisablePin(11, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)0xA2);
		CPU_INTC_ActivateInterrupt(OTG_FS_IRQn,         USBH_ISR, OTG);
	}
	else {
		CPU_GPIO_DisablePin(16+14, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)0xC2);
		CPU_GPIO_DisablePin(16+15, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)0xC2);
		CPU_INTC_ActivateInterrupt(OTG_HS_IRQn,         USBH_ISR, OTG);
	}

	for (int i = 0; i < 3; i++)
	{
		CPU_GPIO_SetPinState(18, 1);
		HAL_Time_Sleep_MicroSeconds(200*1000);
		CPU_GPIO_SetPinState(18, 0);
		HAL_Time_Sleep_MicroSeconds(200*1000);
	}

	//enable interrupt
	OTG->GINTSTS = 0xFFFFFFFF;
	OTG->GAHBCFG |= OTG_GAHBCFG_GINTMSK;
	return TRUE;
}
Пример #10
0
void ApplicationEntryPoint()
{
    UINT32 ComEvent;

    g_State.Initialize();

    ComEvent = 0;
    if(COM_IsSerial(g_State.UsartPort) && (g_State.UsartPort != COM_NULL))
    {
        ComEvent = SYSTEM_EVENT_FLAG_COM_IN;
    }

#if !defined(TARGETLOCATION_RAM)
    g_State.WaitForActivity = (g_State.ProgramCount != 0); // is there a main app?

#else
    g_State.WaitForActivity = FALSE;      // forever
#endif

    {
        UINT32 ButtonsPressed;
        UINT32 ButtonsReleased;
        char   c;

        // clear any events present from startup
        while(Events_Get( SYSTEM_EVENT_FLAG_ALL ));

        // clear any junk from com port buffers
        while(DebuggerPort_Read( g_State.UsartPort, &c, sizeof(c) ));

        // clear any junk from button buffer
        while(Buttons_GetNextStateChange( ButtonsPressed, ButtonsReleased ));
    }

    {
        BOOL       ProcessingSREC     = FALSE;
        BOOL       ProcessingXREC     = FALSE;
        INT32      ProcessingZENFLASH = 0;
        INT32      Mode               = 0;
        INT32      MenuChoice         = 1;      // main application location when USB not enabled
        BOOL       MenuUpdate         = TRUE;
        UINT32     USBEvent           = 0;
        COM_HANDLE ReadPort           = COM_NULL;
        int        MenuOffset         = 1;      // no USB enabled
        INT64      WaitTimeout        = 0;

#if defined(PLATFORM_ARM_MOTE2)
        CPU_GPIO_SetPinState( LED1_GREEN, LED_ON );
#endif

        if(g_State.WaitForActivity)
        {
            WaitTimeout = HAL_Time_CurrentTime() + (INT64)g_State.WaitInterval * (10 * 1000);

            hal_printf( "Waiting %d.%03d second(s) for hex upload\r\n", g_State.WaitInterval / 1000, g_State.WaitInterval % 1000 );
        }
        else
        {
            hal_printf( "Waiting forever for hex upload\r\n" );
        }

        // checking the existence of Usb Driver, all the default values are set to no USB
        if( USB_DEVICE_STATE_NO_CONTROLLER != USB_GetStatus( ConvertCOM_UsbController(g_State.UsbPort) ) )
        {
            g_State.UsingUsb = TRUE;

            MenuChoice = 2;
            MenuOffset = 2;
        }


        while(true)
        {
            if(MenuUpdate)
            {
                MenuUpdate = FALSE;

                LCD_Clear();
                hal_fprintf( STREAM_LCD, "\f");

                switch(Mode)
                {
                case 0:
                    hal_fprintf( STREAM_LCD, "   Zen Boot\r\n\r\n" );

                    hal_fprintf( STREAM_LCD, "%c PortBooter\r\n", MenuChoice == 0 ? '*' : ' ' );

                    if(g_State.UsingUsb)
                    {
                        hal_fprintf( STREAM_LCD, "%c FlashUSB\r\n", MenuChoice == 1 ? '*' : ' ' );
                    }


                    for(int i = 0; i < g_State.ProgramCount; i++)
                    {
                        hal_fprintf( STREAM_LCD, "%c Prg:%08x\r\n", (i+MenuOffset) == MenuChoice ? '*' : ' ', g_State.Programs[i] );
                    }
                    break;

                case 1:
                    hal_printf( "PortBooter v%d.%d.%d.%d\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION);
                    hal_fprintf( STREAM_LCD, "Waiting forever for hex upload\r\n"         );
                    break;

                case 2:
                    hal_fprintf( STREAM_LCD, "FlashUSB\r\n"                       );
                    hal_fprintf( STREAM_LCD, "Waiting forever for hex upload\r\n" );
                    break;
                }
            }

            UINT32 Events = Events_WaitForEvents( ComEvent | SYSTEM_EVENT_FLAG_BUTTON | SYSTEM_EVENT_FLAG_USB_IN, 2000 );

            if(Events & SYSTEM_EVENT_FLAG_BUTTON)
            {
                UINT32 ButtonsPressed;
                UINT32 ButtonsReleased;

                Events_Clear( SYSTEM_EVENT_FLAG_BUTTON );

                while(Buttons_GetNextStateChange( ButtonsPressed, ButtonsReleased ));
                {
                    if(g_State.SerialPortActive == FALSE)
                    {
                        //printf("%02x %02x\r\n", ButtonsPressed, ButtonsReleased);

                        // up
                        if(ButtonsPressed & BUTTON_UP)
                        {
                            switch(Mode)
                            {
                            case 0:
                                MenuChoice = __max( MenuChoice-1, 0 );
                                break;
                            }

                            g_State.WaitForActivity = FALSE;
                            MenuUpdate              = TRUE;
                        }

                        // down
                        if(ButtonsPressed & BUTTON_DOWN)
                        {
                            switch(Mode)
                            {
                            case 0:
                                MenuChoice = __min( MenuChoice+1, g_State.ProgramCount + MenuOffset-1 );
                                break;
                            }

                            g_State.WaitForActivity = FALSE;
                            MenuUpdate              = TRUE;
                        }

                        // enter button
                        if(ButtonsPressed & BUTTON_ENTR)
                        {
                            switch(Mode)
                            {
                            case 0:
                                if(MenuChoice == 0)
                                {
                                    Mode = 1;

                                    //UsingUsb = FALSE;
                                }
                                else if(g_State.UsingUsb && MenuChoice == 1)
                                {
                                    Mode = 2;
                                    USB_Configure( ConvertCOM_UsbController(g_State.UsbPort), &UsbDefaultConfiguration );
                                    USB_Initialize( ConvertCOM_UsbController(g_State.UsbPort) );
                                    USB_OpenStream( ConvertCOM_UsbStream(g_State.UsbPort), USB_DEBUG_EP_WRITE, USB_DEBUG_EP_READ );
                                    //UsingUsb = TRUE;
                                }
                                else
                                {
                                    StartApplication( (void (*)())g_State.Programs[MenuChoice-MenuOffset] );
                                }
                                break;

                            case 1:
                                Mode = 0;
                                break;

                            case 2:
                                // USB_Uninitialize();
                                Mode = 0;
                                break;
                            }

                            g_State.WaitForActivity = FALSE;
                            MenuUpdate              = TRUE;
                        }

                        if(ButtonsReleased)
                        {
                            MenuUpdate = TRUE;
                        }
                    }
                }
            }

            if((Events & ComEvent) || (Events & SYSTEM_EVENT_FLAG_USB_IN))
            {
                char c;

                if(Events & ComEvent)
                {
                    Events_Clear( ComEvent );

                    ReadPort              = g_State.UsartPort;
                    g_State.pStreamOutput = ReadPort;
                }
                else
                {
                    USBEvent = USB_GetEvent( ConvertCOM_UsbController(g_State.UsbPort), USB_EVENT_ALL );
                    if( !(USBEvent & g_State.UsbEventCode) )
                        continue;

                    g_State.pStreamOutput = g_State.UsbPort;
                    ReadPort              = g_State.UsbPort;
                }

                while(DebuggerPort_Read( ReadPort, &c, sizeof(c) ))
                {
                    if(ProcessingSREC)
                    {
                        ProcessingSREC = g_SREC.Process( c );
                    }
                    else if(ProcessingXREC)
                    {
                        ProcessingXREC = g_XREC.Process( c );
                    }
                    else if(ProcessingZENFLASH)
                    {
                        const char Signature[] = "ZENFLASH\r";

                        //printf( "Got %d at %d\r\n", c, ProcessingZENFLASH );
                        if(Signature[ProcessingZENFLASH++] == c)
                        {
                            if(Signature[ProcessingZENFLASH] == 0)
                            {
                                SignalActivity();
                                ProcessingZENFLASH = 0;
                            }
                        }
                        else
                        {
                            ProcessingZENFLASH = 0;
                        }
                    }
                    else if('S' == c)
                    {
                        ProcessingSREC = TRUE;
                    }
                    else if('X' == c)
                    {
                        ProcessingXREC = TRUE;
                    }
                    else if('Z' == c)
                    {
                        ProcessingZENFLASH = 1;
                    }
                }
            }

            if(g_State.WaitForActivity && WaitTimeout < HAL_Time_CurrentTime())
            {
#if defined(PLATFORM_ARM_MOTE2)
                CPU_GPIO_SetPinState(LED1_GREEN, LED_OFF);        // Turn off Green LED for iMOTE2
#endif
                // we didn't see anything on serial port for wait interval (2 seconds nominally),
                // continue with code - just run the normal application
                StartApplication( (void (*)())g_State.Programs[0] );
            }

        }
    }
}
Пример #11
0
    BOOL Process( UINT8 c )
    {
        while(true)
        {
            switch(m_phase)
            {
                //
                // Setup 'address' reception.
                //
            case 0:
                m_ptr = (char*)&m_address;
                m_len = sizeof(m_address);
                m_phase++;
                break;
    
                //
                // Setup 'size' reception.
                //
            case 2:
                //printf( "Got address %08x\r\n", m_address );
    
                m_ptr = (char*)&m_size;
                m_len = sizeof(m_size);
                m_phase++;
                return TRUE;
    
                //
                // Setup 'crc' reception.
                //
            case 4:
                //printf( "Got size %08x\r\n", m_size );
    
                m_ptr = (char*)&m_crc;
                m_len = sizeof(m_crc);
                m_phase++;
                return TRUE;
    
                //
                // Setup 'data' reception or jump to entrypoint.
                //
            case 6:
                //printf( "Got crc %08x\r\n", m_crc );
    
                m_crc += m_address;
                m_crc += m_size;
    
                if(m_size == 0)
                {
                    if(m_crc != 0)
                    {
                        hal_fprintf( g_State.pStreamOutput, "X crc %08x %08x\r\n", m_address, m_crc );
    
                       // bad characters! realign
                        m_phase = 0;
                        return FALSE;
                    }
    
                    hal_fprintf( g_State.pStreamOutput, "X start %08x\r\n", m_address );

#if defined(PLATFORM_ARM_MOTE2)
                    CPU_GPIO_SetPinState(LED1_GREEN, LED_OFF);        // Turn off Green LED for iMote2
#endif                
    
                    StartApplication( (void (*)())m_address );
                }
    
                if(m_size > sizeof(m_data) || (m_size % sizeof(FLASH_WORD)) != 0)
                {
                    hal_fprintf( g_State.pStreamOutput, "X size %d\r\n", m_size );
    
                    // bad characters! realign
                    m_phase = 0;
                    return FALSE;
                }
    
                m_ptr = (char*)m_data;
                m_len =        m_size;
                m_phase++;
                return TRUE;
    
            case 8:
                {
                    FLASH_WORD* src     = (FLASH_WORD*)m_data;
                    FLASH_WORD* dst     = (FLASH_WORD*)m_address;
                    BOOL        success = TRUE;
                    int         i;
                    BlockStorageDevice * pDevice;
                    ByteAddress WriteByteAddress ;
    
                    for(i=0; i<m_size; i++)
                    {
                        m_crc += m_data[i];
                    }
    
                    if(m_crc != 0)
                    {
                        hal_fprintf( g_State.pStreamOutput, "X crc %08x %08x\r\n", m_address, m_crc );
    
                        // bad characters! realign
                        m_phase = 0;
                        return FALSE;
                    }
    
                    SignalActivity();

                    // this slows things down to print every address, only print once per line
                    hal_fprintf( STREAM_LCD, "WR: 0x%08x\r", (UINT32)dst );

                    // if it not Block Device, assume it is RAM 
                    if (BlockStorageList::FindDeviceForPhysicalAddress( & pDevice, m_address, WriteByteAddress))
                    {
                        UINT32 regionIndex, rangeIndex;
                        const BlockDeviceInfo* deviceInfo = pDevice->GetDeviceInfo() ;

                        if(!(pDevice->FindRegionFromAddress(WriteByteAddress, regionIndex, rangeIndex))) 
                        {
#if !defined(BUILD_RTM)
                           hal_printf(" Invalid condition - Fail to find the block number from the ByteAddress %x \r\n",WriteByteAddress);  
#endif
                            return FALSE;
                        }

                        // start from the block where the sector sits.
                        UINT32        iRegion = regionIndex;
                        UINT32        accessPhyAddress = (UINT32)m_address;
                                
                        BYTE*         bufPtr           = (BYTE*)src;
                        BOOL          success          = TRUE;
                        INT32         writeLenInBytes  = m_size;


                        while (writeLenInBytes > 0)
                        {
                            for(; iRegion < deviceInfo->NumRegions; iRegion++)
                            {
                                const BlockRegionInfo *pRegion = &(deviceInfo->Regions[iRegion]);

                                ByteAddress blkAddr = pRegion->Start;

                                while(blkAddr < accessPhyAddress)
                                {
                                    blkAddr += pRegion->BytesPerBlock;
                                }

                                //writeMaxLength =the current largest number of bytes can be read from the block from the address to its block boundary.
                                UINT32 NumOfBytes = __min(pRegion->BytesPerBlock, writeLenInBytes);
                                if (accessPhyAddress == blkAddr && !pDevice->IsBlockErased(blkAddr, pRegion->BytesPerBlock))
                                {
                                    hal_fprintf( STREAM_LCD, "ER: 0x%08x\r", blkAddr );

                                    pDevice->EraseBlock(blkAddr);
                                    blkAddr += pRegion->BytesPerBlock;
                                }
                                success = pDevice->Write(accessPhyAddress , NumOfBytes, (BYTE *)bufPtr, FALSE);

                                writeLenInBytes -= NumOfBytes;
								
                                if ((writeLenInBytes <=0) || (!success)) break;

                                bufPtr += NumOfBytes;

                            }

                            if ((writeLenInBytes <=0) || (!success)) break;
                        }
                        
                    }
                    else
                    {
                        // must be RAM but don't verify, we write anyway, possibly causing a data abort if the address is bogus
                        memcpy( dst, src, m_size );
                    }
    
                    hal_fprintf( g_State.pStreamOutput, "X %s %08x\r\n", success ? "ack" : "nack", m_address );
    
                    m_phase = 0;
                    return FALSE;
                }
                break;
    
                //
                // Read data.
                //
            case 1:
            case 3:
            case 5:
            case 7:
                *m_ptr++ = c; if(--m_len) return TRUE;
    
                m_phase++;
                break;
            }
        }
    }