Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
flash_read.c
00001 /**************************************************************************** 00002 * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd 00003 * 00004 * This file is part of the Satellite Observers Workbench (SOWB). 00005 * 00006 * SOWB is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * SOWB is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with SOWB. If not, see <http://www.gnu.org/licenses/>. 00018 * 00019 * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $ 00020 * 00021 ***************************************************************************/ 00022 00023 #include "sowb.h" 00024 #include "flash.h" 00025 #include "dma.h" 00026 #include "ssp0.h" 00027 #include "gpio.h" 00028 #include "user.h" 00029 #include "debug.h" 00030 00031 bool page_read_in_progress = false; 00032 00033 /* Local function prototypes. */ 00034 static int _flash_read_page(unsigned int page_address, char *buffer); 00035 00036 void flash_read_page(unsigned int page_address, char *buffer, bool block) { 00037 _flash_read_page(page_address, buffer); 00038 00039 if (block) { 00040 while(page_read_in_progress) { 00041 WHILE_WAITING_DO_PROCESS_FUNCTIONS; 00042 } 00043 } 00044 } 00045 00046 /** flash_read_in_progress 00047 */ 00048 bool flash_read_in_progress(void) { 00049 return page_read_in_progress; 00050 } 00051 00052 /** flash_read_page 00053 * 00054 * Load the given flash page into the supplied buffer. 00055 * 00056 * @param unsigned int the page to load, between 0 and 4095 00057 * @param char * buffer The RAM buffer to load the page to. 00058 */ 00059 static int _flash_read_page(unsigned int page_address, char *buffer) { 00060 00061 /* We can't read a page while a write or erase is in progress. */ 00062 if (flash_write_in_progress() || flash_sector_erase_in_progress()) { 00063 return 0; 00064 } 00065 00066 /* Wait for any previous read operation to complete. */ 00067 while (page_read_in_progress) WHILE_WAITING_DO_PROCESS_FUNCTIONS; 00068 00069 /* Mark a read is in operation. */ 00070 page_read_in_progress = true; 00071 00072 /* Request use of SSP0. */ 00073 while(!SSP0_request()) WHILE_WAITING_DO_PROCESS_FUNCTIONS; 00074 00075 /* Ensure the SSP1 RX FIFO is empty. */ 00076 SSP0_FLUSH_RX_FIFO; 00077 00078 /* Send the command and page read to the flash device. */ 00079 FLASH_CS_ASSERT; 00080 FLASH_LONG_COMMAND(FLASH_READ, page_address); 00081 00082 /* We use two DMA channels to achieve the required results. 00083 The higher priority channel0 is used to drive the SSP0 00084 SCLK0 pin with "don't care" bytes. We do this to flush 00085 the bytes out of the flash device. We then use Channel1 00086 to transfer the incoming bytes to RAM. */ 00087 00088 while(!DMA_request_channel(0)) WHILE_WAITING_DO_PROCESS_FUNCTIONS; 00089 while(!DMA_request_channel(1)) WHILE_WAITING_DO_PROCESS_FUNCTIONS; 00090 00091 LPC_GPDMA->DMACIntTCClear = 0x3; 00092 LPC_GPDMA->DMACSoftSReq = 0xC; 00093 00094 /* Prep Channel1 to receive the incoming byte stream. */ 00095 LPC_GPDMACH1->DMACCSrcAddr = (uint32_t)&LPC_SSP0->DR; 00096 LPC_GPDMACH1->DMACCDestAddr = (uint32_t)buffer; 00097 LPC_GPDMACH1->DMACCLLI = 0; 00098 LPC_GPDMACH1->DMACCControl = DMA_CHANNEL_TCIE | DMA_CHANNEL_DST_INC | (uint32_t)FLASH_PAGE_SIZE; 00099 00100 /* Prep Channel0 to send "don't care" bytes in order to clock out the data from the flash device. */ 00101 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)buffer; /* don't care data. */ 00102 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; 00103 LPC_GPDMACH0->DMACCLLI = 0; 00104 LPC_GPDMACH0->DMACCControl = DMA_CHANNEL_TCIE | (uint32_t)FLASH_PAGE_SIZE; 00105 00106 /* Enable SSP0 DMA. */ 00107 LPC_SSP0->DMACR = 0x3; 00108 00109 /* Enable Channel0 */ 00110 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | 00111 DMA_CHANNEL_DST_PERIPHERAL_SSP0_TX | 00112 DMA_TRANSFER_TYPE_M2P | 00113 DMA_MASK_IE | 00114 DMA_MASK_ITC; 00115 00116 /* Wait until at least one byte has arrived into the RX FIFO 00117 and then start-up the Channel1 DMA to begin transferring them. */ 00118 while((LPC_SSP0->SR & (1UL << 2)) == 0); 00119 00120 /* Enable Channel1 */ 00121 LPC_GPDMACH1->DMACCConfig = DMA_CHANNEL_ENABLE | 00122 DMA_CHANNEL_SRC_PERIPHERAL_SSP0_RX | 00123 DMA_TRANSFER_TYPE_P2M | 00124 DMA_MASK_IE | 00125 DMA_MASK_ITC; 00126 00127 /* SSP0 CS line and "page_read_in_progress" flag are now 00128 under DMA/SSP0 interrupt control. See the DMA ISR handlers 00129 and SSP0 ISR handlers for more information. */ 00130 00131 return 1; 00132 } 00133 00134 /** flash_read_ssp0_irq 00135 * 00136 * Called by the SSP0 ISR handler. 00137 */ 00138 int flash_read_ssp0_irq(void) { 00139 if (page_read_in_progress) { 00140 if (LPC_SSP0->MIS & (1UL << 3)) { 00141 LPC_SSP0->IMSC &= ~(1UL << 3); 00142 while(SSP0_IS_BUSY); 00143 FLASH_CS_DEASSERT; 00144 SSP0_release(); 00145 page_read_in_progress = false; 00146 return 1; 00147 } 00148 } 00149 return 0; 00150 } 00151 00152 /* The following two functions are the DMA ISR handlers. They are 00153 called from dma.c so see that module for more details. */ 00154 00155 /** flash_read_dma0_irq 00156 */ 00157 int flash_read_dma0_irq(int channel_number) { 00158 if (page_read_in_progress) { 00159 LPC_GPDMACH0->DMACCConfig = 0; 00160 DMA_release_channel(0); 00161 return 1; 00162 } 00163 return 0; 00164 } 00165 00166 /** flash_read_dma1_irq 00167 */ 00168 int flash_read_dma1_irq(int channel_number) { 00169 if (page_read_in_progress) { 00170 LPC_GPDMACH1->DMACCConfig = 0; 00171 DMA_release_channel(1); 00172 LPC_SSP0->IMSC = (1UL << 3); 00173 return 1; 00174 } 00175 return 0; 00176 } 00177
Generated on Tue Jul 12 2022 18:05:35 by 1.7.2