/*! \file smartmedia.hcc * * \section generic Here we interface with the SmartMedia card. * * \section project Project information. * Project Graphic Equalizer\n * \author O.M. Schinagl * \date 20041110 * \version 0.1 * * \section copyright Copyright * Copyright ©2004 Koninklijke Philips Electronics N.V. All rights reserved * * \section history Change history * 20041110: O.M. Schinagl\n Initial version * ********************************************************************/ /******** System Includes *************/ #include #include "pal_master.hch" /******** Application Includes ********/ #include "configuration.hch" #include "display_shared.hch" #include "smartmedia_shared.hch" #include "smartmedia.hch" #if HAVE_DEBUG #include "debug.hch" #endif #include "audio.hch" #include "mouse_shared.hch" #include "eventhandler_shared.hch" #include "display.hch" /* FIXME: temporary include, needs to be moved to 'init' */ unsigned 1 physical_format; unsigned 2 current_track; static rom unsigned 27 track_start[4] = { SMARTMEDIA_ADDRESS_TRACK1_START, SMARTMEDIA_ADDRESS_TRACK2_START, SMARTMEDIA_ADDRESS_TRACK3_START }; static rom unsigned 27 track_end[4] = { SMARTMEDIA_ADDRESS_TRACK1_END, SMARTMEDIA_ADDRESS_TRACK2_END, SMARTMEDIA_ADDRESS_TRACK3_END }; /*! \fn unsigned 1 smartmedia_init(void); * \brief We here initialize the Smart Media card and verify wether the * card is inserted and such. * * \return We return 0 on success, 1 on error. * \retval unsigned 1 */ inline unsigned 1 smartmedia_init(void) { unsigned 1 retval; /* * Firstly we enable both the CPLD. */ RC200CPLDEnable(); /* * We must reset the Smart Media before initializing it. If we don't reset it * we get a lot of Init failures. If we don't use the delay, we get a lot of * init failures. */ RC200SmartMediaReset(&retval); delay; RC200SmartMediaInit(&retval); /* * Before we enter our main Smart Media read loop we verify the format * of the SMC. This to ensure we use the correct functions later. */ RC200SmartMediaCheckLogicalFormat(&physical_format); current_track = 0; return retval; } /* --- smartmedia_init() --- */ /*! \fn void smartmedia_loaddata(skindata_t *skindata); * \brief We load our memory with skin and help data from the smartmedia. * * \param *skindata skindata like boundries and colors of elements. * * \return void * \retval void */ void smartmedia_loaddata(skindata_t *skindata) { /* * Setup RAM Handle, and determin maximum Data and Address widths * * FIXME: Currently we set the Ram handle here and in the main. If we * would want to change it here, also change it elsewhere. A better * solution would be to have the RAM_BANK0 macro defined somewhere * globally. */ macro expr RAM_BANK0 = PalPL2RAMCT(0); macro expr DW = PalPL2RAMGetMaxDataWidthCT(); macro expr AW = PalPL2RAMGetMaxAddressWidthCT(); unsigned DW data; unsigned 27 sm_address; unsigned AW address, address_end; unsigned 8 mask, r, g, b; unsigned 4 stage; unsigned 1 result; extern ram unsigned 8 presets_default_values[768]; /* * We have several stages to go through. We stop once we pass the last * one. */ while ((STAGE_LOAD_INPUT_SELECT_HELP_TEXT +1) != stage) { /* * For each iteration of the main loop we set a different * start and end variables. */ switch (stage) { case STAGE_LOAD_DEMO_PRESET: sm_address = SMARTMEDIA_ADDRESS_PRESET_DEMO_START; address = INDEX_PRESET_DEMO_START; address_end = INDEX_PRESET_DEMO_END; break; case STAGE_LOAD_RESET_PRESET: sm_address = SMARTMEDIA_ADDRESS_PRESET_RESET_START; address = INDEX_PRESET_RESET_START; address_end = INDEX_PRESET_RESET_END; break; case STAGE_LOAD_SKIN: sm_address = SMARTMEDIA_ADDRESS_SKIN_START; address = ADDRESS_SKIN_START; address_end = ADDRESS_SKIN_END; break; case STAGE_LOAD_HELP: sm_address = SMARTMEDIA_ADDRESS_HELP_START; address = ADDRESS_HELP_START; address_end = ADDRESS_HELP_END; break; case STAGE_LOAD_GRAPH: sm_address = SMARTMEDIA_ADDRESS_GRAPH_START; address = ADDRESS_GRAPH_START; address_end = ADDRESS_GRAPH_END; break; case STAGE_LOAD_TOP_FONTYS: sm_address = SMARTMEDIA_ADDRESS_TOP_FONTYS_START; address = ADDRESS_ABOUT_TOP_FONTYS_START; address_end = ADDRESS_ABOUT_TOP_FONTYS_END; break; case STAGE_LOAD_TOP_TASS: sm_address = SMARTMEDIA_ADDRESS_TOP_TASS_START; address = ADDRESS_ABOUT_TOP_TASS_START; address_end = ADDRESS_ABOUT_TOP_TASS_END; break; case STAGE_LOAD_TOP_TRANSFER: sm_address = SMARTMEDIA_ADDRESS_TOP_TRANSFER_START; address = ADDRESS_ABOUT_TOP_TRANSFER_START; address_end = ADDRESS_ABOUT_TOP_TRANSFER_END; break; case STAGE_LOAD_TOP_CELOXICA: sm_address = SMARTMEDIA_ADDRESS_TOP_CELOXICA_START; address = ADDRESS_ABOUT_TOP_CELOXICA_START; address_end = ADDRESS_ABOUT_TOP_CELOXICA_END; break; /* case STAGE_LOAD_TOP_DETAILS: sm_address = SMARTMEDIA_ADDRESS_TOP_DETAILS_START; address = ADDRESS_ABOUT_TOP_DETAILS_START; address_end = ADDRESS_ABOUT_TOP_DETAILS_END; break; */ case STAGE_LOAD_ABOUT_BOTTOM: sm_address = SMARTMEDIA_ADDRESS_BOTTOM_START; address = ADDRESS_ABOUT_BOTTOM_START; address_end = ADDRESS_ABOUT_BOTTOM_END; break; case STAGE_LOAD_AUDIO_PLAYER: sm_address = SMARTMEDIA_ADDRESS_AUDIO_PLAYER_START; address = ADDRESS_AUDIO_PLAYER_START; address_end = ADDRESS_AUDIO_PLAYER_END; break; case STAGE_LOAD_INPUT_SELECT_TEXT: sm_address = SMARTMEDIA_ADDRESS_INPUT_SELECT_TEXT_START; address = ADDRESS_INPUT_SELECT_TEXT_START; address_end = ADDRESS_INPUT_SELECT_TEXT_END; break; case STAGE_LOAD_INPUT_SELECT_HELP_TEXT: sm_address = SMARTMEDIA_ADDRESS_INPUT_SELECT_TEXT_HELP_START; address = ADDRESS_INPUT_SELECT_TEXT_HELP_START; address_end = ADDRESS_INPUT_SELECT_TEXT_HELP_END; break; default: break; } /* * TODO: Replace the above switch-case with a lookuptables. */ /* * The only difference between logical and phyiscally formated * SMCs codewise is how they are addressed. */ if (physical_format) { RC200SmartMediaSetAddress(READ, sm_address); } else { RC200SmartMediaSetLogicalAddress(READ, sm_address); } /* * While the address hasn't reached the end, continue loading data. */ while (address != address_end) { /* * No matter what we read from the SMC, we aways need to * read at least one byte per iteration. (Otherwise there * would be no point in entering this loop. */ RC200SmartMediaRead(&mask, FALSE); /* * The difference when loading data from the SMC is * when we load the presets. These aren't stored in * external RAM but in an array on the FPGA. */ if ((STAGE_LOAD_DEMO_PRESET == stage) || (STAGE_LOAD_RESET_PRESET == stage)) { /* * We only read one byte from the SMC and thus * we only store one byte. We re-use the 'mask' * variable here. The address is also re-used * and thus we only use the last 10 bits to fit * the address in our index. * */ presets_default_values[address <- 10] = mask; } else { /* * All other data has RGB image data and thus * we read those additional bytes from the SMC. * The image used for the graphic visualization * is packed together however and thus we * re-use the rgb variables here. */ RC200SmartMediaRead(&r, FALSE); RC200SmartMediaRead(&g, FALSE); RC200SmartMediaRead(&b, FALSE); /* * There needs to be atleast one clock cycle * between setting the address and reading * from it. We therefore set the address before * reading from the SmartMedia as 'delay'. */ PalPL2RAMSetWriteAddress(RAM_BANK0, address); /* * FIXME: Do we need this even? */ data = 0 @ mask @ r @ g @ b; /* * Now that we read a while 32bit wide word * we can store it in the main memory bank. */ PalPL2RAMWrite(RAM_BANK0, data); } #if HAVE_DEBUG /* * Print some indication about data loading. */ if (!(address <- 14)) {; print_string("."); } #endif /* * Finally we increase our address to prepare for the * next iteration. */ address++; } /* * We need to tell the SmartMedia that the last byte was read * however to check wether it is the last byte during each * iteration of the loop would unecasserly 'a lot' of * resources. We therefore read a dummy byte here. It doesn't * matter where it comes from (from the SMC) as we don't use * it. */ RC200SmartMediaRead(&mask, TRUE); /* * Because we need to set a new starting address in the next * iteration we need to 'end' the SmartMedia Operation. */ RC200SmartMediaOperationEnd(&result); /* * We are done with this 'stage' and continue to the next one. */ stage++; } if (physical_format) { RC200SmartMediaSetAddress(READ, 0); } else { RC200SmartMediaSetLogicalAddress(READ, 0); } /* * TODO: This block needs to move up into the loop where we calculate * these settings determind by the image data. */ skindata->spectrum.top = 200; skindata->spectrum.bottom = 335; skindata->spectrum.left = 77; skindata->spectrum.right = 575; // skindata->spectrum.color_primary = PIXEL_SPECTRUM; // skindata->spectrum.color_secondary = PIXEL_SPECTRUM; skindata->waveform.top = 46; skindata->waveform.bottom = 118; skindata->waveform.left = 76; skindata->waveform.right = 413; skindata->waveform.color_primary = PIXEL_WAVEFORM; skindata->volume.top = 66; skindata->volume.bottom = 112; skindata->volume.left = 431; skindata->volume.right = 448; skindata->volume.color_primary = PIXEL_VOLUME; skindata->inputgain.top = 66; skindata->inputgain.bottom = 112; skindata->inputgain.left = 450; skindata->inputgain.right = 467; skindata->inputgain.color_primary = PIXEL_INPUTGAIN_NORM; skindata->inputgain.color_secondary = PIXEL_INPUTGAIN_SAT; skindata->equalizer.color_primary = PIXEL_EQUALIZER; } /* --- smartmedia_loaddata() --- */ /* smartmedia_load_block() { setaddress(); for () { smart_read(); } end(); }*/ void change_track(unsigned 2 track_index) { current_track = track_index; } unsigned 1 load_audio_samples(signed 18 *samples, unsigned 27 blockoffset, unsigned 7 sample_count) { ram unsigned 8 data[128]; unsigned 16 sampleword; unsigned 8 sampleindex, samplebyte, samplecount; unsigned 1 result; unsigned 1 retval; samplecount = (0 @ sample_count) <<1; sampleindex = 0; retval = 0; if (!blockoffset) { smartmedia_set_read_address(track_start[current_track]); } smartmedia_read_bytes(data, samplecount); while (sampleindex != samplecount) { samplebyte = data[sampleindex <- 7]; sampleword = samplebyte @ data[(sampleindex +1) <- 7]; samples[sampleindex >>1] = (signed 18)(sampleword @ 0); sampleindex +=2; } if (((blockoffset <<7) +(0 @ samplecount) +track_start[current_track]) >= track_end[current_track]) { retval = 1; } return retval; } void smartmedia_set_read_address(unsigned 27 address) { unsigned 8 dummy; unsigned 1 result; /* * Read dummy value to signal the SmartMedia card reader * that the last byte is read from the SmartMedia card */ RC200SmartMediaRead(&dummy, TRUE); RC200SmartMediaOperationEnd(&result); /* * Check the format of the SmartMedia card and set the address accordingly */ if (physical_format) { RC200SmartMediaSetAddress(READ, address); } else { RC200SmartMediaSetLogicalAddress(READ, address); } } void smartmedia_read_bytes(unsigned 8 *data, unsigned 8 bytecount) { unsigned 8 byteindex; unsigned 8 temp; byteindex = 0; while (byteindex != bytecount) { RC200SmartMediaRead(&temp, FALSE); data[byteindex] = temp; byteindex++; } }