BOOL ParseLine( const char* SRECLine ) { UINT32 Address; int i; UINT32 BytesRemaining = 0; UINT32 Temp = 0; UINT32 Data32; UINT32 RecordType; UINT32 CheckSum; UINT32 WordCount = 0; UINT32 ByteCount = 0; FLASH_WORD WordData[16/sizeof(FLASH_WORD)]; // we support 16 bytes of data per record max, 4 words, 8 shorts UINT8 ByteData[16]; // we support 16 bytes of data per record max, 4 words, 8 shorts BlockStorageDevice *pDevice; UINT32 m_size; ByteAddress WriteByteAddress; RecordType = *SRECLine++; SRECLine = htoi( SRECLine, 2, BytesRemaining ); if(!SRECLine) return FALSE; // start the checksum with this byte CheckSum = BytesRemaining; // get the destination address // do bytes only to make checksum calc easier Data32 = 0; for(i = 0; i < 4; i++) { SRECLine = htoi( SRECLine, 2, Temp ); if(!SRECLine) return FALSE; CheckSum += Temp; Data32 <<= 8; Data32 |= Temp; BytesRemaining -= 1; } Address = Data32; // take off one byte for CRC; m_size = BytesRemaining -1; switch(RecordType) { case '3': { while(BytesRemaining > 1) { // get bytes into words, and checksum Data32 = 0; for(i = 0; i < sizeof(FLASH_WORD); i++) { SRECLine = htoi( SRECLine, 2, Temp ); if(!SRECLine) return FALSE; CheckSum += Temp; Data32 |= Temp << (i*8); // little endian format ByteData[ByteCount++] = Temp; BytesRemaining -= 1; // leave the checksum in place if(1 == BytesRemaining) break; } ASSERT(WordCount < (16/sizeof(FLASH_WORD))); WordData[WordCount++] = Data32; } } break; case '7': // just a return address (starting location) m_StartAddress = (UINT32)Address; break; default: // we only support S3 and S7 records, for now return FALSE; } // get the checksum SRECLine = htoi( SRECLine, 2, Temp ); if(!SRECLine) return FALSE; CheckSum += Temp; BytesRemaining -= 1; ASSERT(0 == BytesRemaining); // make sure we had a NULL terminator for line, and not more characters if(*SRECLine != 0) { return FALSE; } if(0xff != (CheckSum & 0xff)) { return FALSE; } else { // only write if we succeeded the checksum entirely for whole line if(m_size > 0) { SignalActivity(); // this slows things down to print every address, only print once per line hal_fprintf( STREAM_LCD, "WR: 0x%08x\r", (UINT32)Address ); if (BlockStorageList::FindDeviceForPhysicalAddress( &pDevice, 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)Address; BYTE* bufPtr = (BYTE*)ByteData; 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 { FLASH_WORD *Addr = (FLASH_WORD *) Address; for(i = 0; i < WordCount; i++) { // must be RAM but don't verify, we write anyway, possibly causing a data abort if the address is bogus *Addr++ = WordData[i]; } } } } return TRUE; }
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; } } }
void ApplicationEntryPoint() { #if defined(TEST_DAC) UINT32 FramesNum = g_LPC24XX_DAC_Driver.GetBufferFrameCapacity(); if (DAC_FRAME_BUFFERS_NUM!=FramesNum) { debug_printf( "Error, BufferFrameCapacity != DAC_FRAME_BUFFERS_NUM: %d != %d.\r\n", FramesNum, DAC_FRAME_BUFFERS_NUM ); } UINT32 nextInFrameOffset=0; UINT16 frameLength = MAX_DECODED_FRAME_SIZE/2; short* frameSignedStart = NULL; LPC24XX_VIC& VIC = LPC24XX::VIC(); /*debug_printf("VIC INTRSEL = 0x%08x\r\n", VIC.INTRSEL); VIC.INTRSEL |= 1 << LPC24XX_TIMER::getIntNo(LPC24XX_DAC::Timer); debug_printf("new VIC INTRSEL = 0x%08x\r\n", VIC.INTRSEL);*/ VIC.VECTPRIORITY[LPC24XX_TIMER::getIntNo(LPC24XX_DAC::Timer)] = 0; for(int i= 0; i< 32; i++) { debug_printf("PRIO INTR%02d = %d \r\n", i,VIC.VECTPRIORITY[i]); } debug_printf( "Init DAC, 8kHz output.\r\n" ); g_LPC24XX_DAC_Driver.Initialize(OUT_FREQ); debug_printf( "BUFFER PRE-FILL TEST.\r\n" ); debug_printf( "Adding frames to the DAC driver buffer: " ); debug_printf("total frames to be added = %d\r\n", TEST_SAMPLES_NUM/MAX_DECODED_FRAME_SIZE-CUTOUT); debug_printf("DAC frame buffers available = %d\r\n", DAC_FRAME_BUFFERS_NUM); if(DAC_FRAME_BUFFERS_NUM<(TEST_SAMPLES_NUM/MAX_DECODED_FRAME_SIZE-CUTOUT)) debug_printf("ONLY THE FIRST %d FRAMES OF THE SAMPLE WILL BE PLAYED.\r\n", DAC_FRAME_BUFFERS_NUM); while(nextInFrameOffset+(MAX_DECODED_FRAME_SIZE*CUTOUT) < TEST_SAMPLES_NUM) { //if(i%(1024*256)) continue; frameSignedStart = (short*)(bin_data+nextInFrameOffset); if(g_LPC24XX_DAC_Driver.AddFrame(frameSignedStart, frameLength)) { debug_printf( " done.\r\n" ); nextInFrameOffset+=MAX_DECODED_FRAME_SIZE; } else { debug_printf( "Buffer full, starting playout.\r\n"); break; } } resetDACISRTiming(); debug_printf( "DAC.On() in 2 seconds\r\n"); Events_WaitForEvents( 0, 2000 ); if(!hijackISRs()) return; if(g_LPC24XX_DAC_Driver.On()) { //debug_printf( "Done. 2sec wait.\r\n" ); don't output to avoid adding serial activity during the test } else { debug_printf( "FAILED.\r\n" ); } while(g_LPC24XX_DAC_Driver.GetBufferLevel()>0) { //debug_printf("Samples left: %d\r\n", g_LPC24XX_DAC_Driver.GetBufferLevel()); //debug_printf("Frames left: %d\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); } //stop logging interrupts before starting to output again int finalIrqCount = irq_count; irq_count = 8192; Events_WaitForEvents( 0, 5000 ); if(!restoreISRs()) return; debug_printf("%d frames left.\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); debug_printf("Final IRQ count = %u\r\n", finalIrqCount); debug_printf( "BUFFER PRE-FILL TEST OVER.\r\n"); displayRunTestResults(); debug_printf("CSV DATA OUTPUT FOLLOWS\r\n"); //csvRunTestResults(); debug_printf("\r\nPARALLEL BUFFER FILL TEST\r\n" ); Events_WaitForEvents( 0, 3000 ); debug_printf( "DAC.Off()\r\n"); if(g_LPC24XX_DAC_Driver.Off()) { debug_printf( "Done.\r\n" ); } else { debug_printf( "FAILED.\r\n" ); } debug_printf( "Uninit DAC\r\n"); g_LPC24XX_DAC_Driver.Uninitialize(); debug_printf( "Done.\r\n"); debug_printf( "Init DAC, 8kHz output.\r\n" ); g_LPC24XX_DAC_Driver.Initialize(OUT_FREQ); resetDACISRTiming(); debug_printf( "DAC.On() in 2 seconds\r\n"); Events_WaitForEvents( 0, 2000 ); if(g_LPC24XX_DAC_Driver.On()) { //debug_printf( "Done.\r\n" ); } else { debug_printf( "FAILED.\r\n" ); } debug_printf( "Adding frames to the DAC driver buffer: " ); nextInFrameOffset=0; debug_printf("total frames to be added = %d\r\n", TEST_SAMPLES_NUM/MAX_DECODED_FRAME_SIZE-CUTOUT); //FILL JUST ONCE while(nextInFrameOffset+(MAX_DECODED_FRAME_SIZE*CUTOUT) < TEST_SAMPLES_NUM) { //if(i%(1024*256)) continue; frameSignedStart = (short*)(bin_data+nextInFrameOffset); if(g_LPC24XX_DAC_Driver.AddFrame(frameSignedStart, frameLength)) { debug_printf( " done.\r\n" ); nextInFrameOffset+=MAX_DECODED_FRAME_SIZE; } else { //debug_printf( "FAIL.\r\n"); } } while(g_LPC24XX_DAC_Driver.GetBufferLevel()>0) { //debug_printf("Samples left: %d\r\n", g_LPC24XX_DAC_Driver.GetBufferLevel()); //debug_printf("Frames left: %d\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); } Events_WaitForEvents( 0, 3000 ); displayRunTestResults(); debug_printf("CSV DATA OUTPUT FOLLOWS\r\n"); csvRunTestResults(); /*CONTINUOUS REFILL with samples while(true) { //if(i%(1024*256)) continue; frameSignedStart = (short*)(bin_data+nextInFrameOffset); if(g_LPC24XX_DAC_Driver.AddFrame(frameSignedStart, frameLength)) { //debug_printf( " done.\r\n" ); nextInFrameOffset+=MAX_DECODED_FRAME_SIZE; if(nextInFrameOffset+(MAX_DECODED_FRAME_SIZE*CUTOUT)>=TEST_SAMPLES_NUM) nextInFrameOffset = 0; } else { //debug_printf( "FAIL.\r\n"); } debug_printf("Samples left: %d\r\n", g_LPC24XX_DAC_Driver.GetBufferLevel()); debug_printf("Frames left: %d\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); }*///end continuous refill debug_printf("%d frames left.\r\n", g_LPC24XX_DAC_Driver.GetFramesLeft()); debug_printf( "PARALLEL BUFFER FILL TEST OVER.\r\n\r\n" ); //Events_WaitForEvents( 0, 10000 ); debug_printf( "DAC.Off()\r\n"); if(g_LPC24XX_DAC_Driver.Off()) { debug_printf( "Done.\r\n" ); } else { debug_printf( "FAILED.\r\n" ); } debug_printf( "Uninit DAC()\r\n"); g_LPC24XX_DAC_Driver.Uninitialize(); debug_printf( "Done.\r\n"); #endif #if defined(TEST_JOYSTICK) extern LPC24XX_GPIO_Driver g_LPC24XX_GPIO_Driver; wait_joystick = true; for(UINT32 pin = LPC24XX_GPIO::c_P2_22; pin < LPC24XX_GPIO::c_P2_28; pin++) { if(pin == LPC24XX_GPIO::c_P2_24) continue; if(!g_LPC24XX_GPIO_Driver.EnableInputPin( pin, false, joystickISR, NULL, GPIO_INT_EDGE_HIGH, (GPIO_RESISTOR)2 )) { debug_printf("Cannot enable pin %u as INPUT pin.\r\n", pin); exit(1); } debug_printf("Enabled pin %u as INPUT pin.\r\n", pin); } while(wait_joystick) {}; #endif #if defined(TEST_SST39WF) while(1) { lcd_printf ( "Hello, world from the LCD!\r\n" ); hal_printf ( "Hello, world from the HAL!\r\n" ); debug_printf( "Hello, world from the debug intf!\r\n" ); if(BlockStorageList::GetNumDevices() != 1) { debug_printf( "%d Block Devices present!\r\n", BlockStorageList::GetNumDevices() ); break; } BlockStorageDevice* SST = BlockStorageList::GetFirstDevice(); if(SST == NULL) { debug_printf( "GetFirstDevice failed.\r\n" ); break; } const BlockDeviceInfo* SSTInfo = SST->GetDeviceInfo(); if(SSTInfo == NULL) { debug_printf( "GetDeviceInfo failed.\r\n" ); break; } debug_printf( "NumRegions in BSDevice: %d\r\n", SSTInfo->NumRegions); ByteAddress PhyAddress = (ByteAddress) 0xC0FFEEEE; SectorAddress SectAddress = 0xC0FFEEEE; UINT32 RangeIndex; UINT32 RegionIndex; const BlockRegionInfo *pBlockRegionInfo; SST->FindForBlockUsage( /*UINT32*/ BlockRange::BLOCKTYPE_DEPLOYMENT , PhyAddress , RegionIndex, RangeIndex ); if(PhyAddress == 0xC0FFEEEE) { debug_printf( "FindForBlockUsage failed.\r\n" ); break; } debug_printf( "Sector 0x%08x physical address: 0x%08x\r\n", SectAddress, PhyAddress); BYTE pSectorBuf[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; //ERASE before writing! if(!SST->IsBlockErased(PhyAddress, 0x1000)) { debug_printf( "Erasing block " ); if(!SST->EraseBlock(SectAddress)) { debug_printf( "failed.\r\n" ); break; } debug_printf( "successful.\r\n" ); } if(SST->Write(/*UINT32*/ PhyAddress, /*UINT32 NumOfBytes*/ 16, /*BYTE* */ pSectorBuf, /*SectorMetadata* */ FALSE)) debug_printf( "Correctly written 16 bytes to Sector 0x%08x\r\n", SectAddress); Events_WaitForEvents( 0, 2000 ); } #endif //TEST_SST39WF #if defined(TEST_PWM) PWM_Initialize(PWM_CHANNEL_0); // NOTE: on the EA_LPC2478 board the first pin we will return is the 11th pin on the left side from the top of the J1 connector GPIO_PIN pin = PWM_GetPinForChannel( PWM_CHANNEL_0 ); // from 90% to 2/3, to 50%, to 1/3 to 10% float dc[5] = { 0.9, 0.666, 0.5, 0.333, 0.1 }; UINT32 period1 = 1000; // 1Kxz for(UINT32 idx = 0; idx < 5; ++idx) { UINT32 duration1 = (UINT32)((float)period1 * dc[idx]); PWM_ApplyConfiguration( PWM_CHANNEL_0, pin, period1, duration1, FALSE); PWM_Start ( PWM_CHANNEL_0, pin ); // 2 secs, then change HAL_Time_Sleep_MicroSeconds_InterruptEnabled(1 * 1000 * 1000); //Events_WaitForEvents( 0, 2 * 1000); PWM_Stop ( PWM_CHANNEL_0, pin ); } // from 10Khz to 1Khz, 50% duty cycle for(UINT32 period = 10000; period >= 1000; period -= 1000) { UINT32 duration = period / 2; PWM_ApplyConfiguration( PWM_CHANNEL_0, pin, period, duration, FALSE); PWM_Start ( PWM_CHANNEL_0, pin ); // 2 secs, then change HAL_Time_Sleep_MicroSeconds_InterruptEnabled(1 * 1000 * 1000); //Events_WaitForEvents( 0, 2 * 1000); PWM_Stop ( PWM_CHANNEL_0, pin ); } PWM_Uninitialize(PWM_CHANNEL_0); #endif // TEST_PWM while(1) { lcd_printf ( "Hello, world!\r\n" ); hal_printf ( "Hello, world!\r\n" ); debug_printf( "Hello, world!\r\n" ); Events_WaitForEvents( 0, 1000 ); } }