Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.

Dependencies:   mbed

Committer:
AjK
Date:
Mon Oct 11 10:34:55 2010 +0000
Revision:
0:0a841b89d614
Totally Alpha quality as this project isn\t completed. Just publishing it as it answers many questions asked in the forums

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AjK 0:0a841b89d614 1 /****************************************************************************
AjK 0:0a841b89d614 2 * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd
AjK 0:0a841b89d614 3 *
AjK 0:0a841b89d614 4 * This file is part of the Satellite Observers Workbench (SOWB).
AjK 0:0a841b89d614 5 *
AjK 0:0a841b89d614 6 * SOWB is free software: you can redistribute it and/or modify
AjK 0:0a841b89d614 7 * it under the terms of the GNU General Public License as published by
AjK 0:0a841b89d614 8 * the Free Software Foundation, either version 3 of the License, or
AjK 0:0a841b89d614 9 * (at your option) any later version.
AjK 0:0a841b89d614 10 *
AjK 0:0a841b89d614 11 * SOWB is distributed in the hope that it will be useful,
AjK 0:0a841b89d614 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
AjK 0:0a841b89d614 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
AjK 0:0a841b89d614 14 * GNU General Public License for more details.
AjK 0:0a841b89d614 15 *
AjK 0:0a841b89d614 16 * You should have received a copy of the GNU General Public License
AjK 0:0a841b89d614 17 * along with SOWB. If not, see <http://www.gnu.org/licenses/>.
AjK 0:0a841b89d614 18 *
AjK 0:0a841b89d614 19 * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $
AjK 0:0a841b89d614 20 *
AjK 0:0a841b89d614 21 ***************************************************************************/
AjK 0:0a841b89d614 22
AjK 0:0a841b89d614 23 #include "sowb.h"
AjK 0:0a841b89d614 24 #include "flash.h"
AjK 0:0a841b89d614 25 #include "dma.h"
AjK 0:0a841b89d614 26 #include "ssp0.h"
AjK 0:0a841b89d614 27 #include "gpio.h"
AjK 0:0a841b89d614 28 #include "user.h"
AjK 0:0a841b89d614 29 #include "debug.h"
AjK 0:0a841b89d614 30
AjK 0:0a841b89d614 31 bool page_read_in_progress = false;
AjK 0:0a841b89d614 32
AjK 0:0a841b89d614 33 /* Local function prototypes. */
AjK 0:0a841b89d614 34 static int _flash_read_page(unsigned int page_address, char *buffer);
AjK 0:0a841b89d614 35
AjK 0:0a841b89d614 36 void flash_read_page(unsigned int page_address, char *buffer, bool block) {
AjK 0:0a841b89d614 37 _flash_read_page(page_address, buffer);
AjK 0:0a841b89d614 38
AjK 0:0a841b89d614 39 if (block) {
AjK 0:0a841b89d614 40 while(page_read_in_progress) {
AjK 0:0a841b89d614 41 WHILE_WAITING_DO_PROCESS_FUNCTIONS;
AjK 0:0a841b89d614 42 }
AjK 0:0a841b89d614 43 }
AjK 0:0a841b89d614 44 }
AjK 0:0a841b89d614 45
AjK 0:0a841b89d614 46 /** flash_read_in_progress
AjK 0:0a841b89d614 47 */
AjK 0:0a841b89d614 48 bool flash_read_in_progress(void) {
AjK 0:0a841b89d614 49 return page_read_in_progress;
AjK 0:0a841b89d614 50 }
AjK 0:0a841b89d614 51
AjK 0:0a841b89d614 52 /** flash_read_page
AjK 0:0a841b89d614 53 *
AjK 0:0a841b89d614 54 * Load the given flash page into the supplied buffer.
AjK 0:0a841b89d614 55 *
AjK 0:0a841b89d614 56 * @param unsigned int the page to load, between 0 and 4095
AjK 0:0a841b89d614 57 * @param char * buffer The RAM buffer to load the page to.
AjK 0:0a841b89d614 58 */
AjK 0:0a841b89d614 59 static int _flash_read_page(unsigned int page_address, char *buffer) {
AjK 0:0a841b89d614 60
AjK 0:0a841b89d614 61 /* We can't read a page while a write or erase is in progress. */
AjK 0:0a841b89d614 62 if (flash_write_in_progress() || flash_sector_erase_in_progress()) {
AjK 0:0a841b89d614 63 return 0;
AjK 0:0a841b89d614 64 }
AjK 0:0a841b89d614 65
AjK 0:0a841b89d614 66 /* Wait for any previous read operation to complete. */
AjK 0:0a841b89d614 67 while (page_read_in_progress) WHILE_WAITING_DO_PROCESS_FUNCTIONS;
AjK 0:0a841b89d614 68
AjK 0:0a841b89d614 69 /* Mark a read is in operation. */
AjK 0:0a841b89d614 70 page_read_in_progress = true;
AjK 0:0a841b89d614 71
AjK 0:0a841b89d614 72 /* Request use of SSP0. */
AjK 0:0a841b89d614 73 while(!SSP0_request()) WHILE_WAITING_DO_PROCESS_FUNCTIONS;
AjK 0:0a841b89d614 74
AjK 0:0a841b89d614 75 /* Ensure the SSP1 RX FIFO is empty. */
AjK 0:0a841b89d614 76 SSP0_FLUSH_RX_FIFO;
AjK 0:0a841b89d614 77
AjK 0:0a841b89d614 78 /* Send the command and page read to the flash device. */
AjK 0:0a841b89d614 79 FLASH_CS_ASSERT;
AjK 0:0a841b89d614 80 FLASH_LONG_COMMAND(FLASH_READ, page_address);
AjK 0:0a841b89d614 81
AjK 0:0a841b89d614 82 /* We use two DMA channels to achieve the required results.
AjK 0:0a841b89d614 83 The higher priority channel0 is used to drive the SSP0
AjK 0:0a841b89d614 84 SCLK0 pin with "don't care" bytes. We do this to flush
AjK 0:0a841b89d614 85 the bytes out of the flash device. We then use Channel1
AjK 0:0a841b89d614 86 to transfer the incoming bytes to RAM. */
AjK 0:0a841b89d614 87
AjK 0:0a841b89d614 88 while(!DMA_request_channel(0)) WHILE_WAITING_DO_PROCESS_FUNCTIONS;
AjK 0:0a841b89d614 89 while(!DMA_request_channel(1)) WHILE_WAITING_DO_PROCESS_FUNCTIONS;
AjK 0:0a841b89d614 90
AjK 0:0a841b89d614 91 LPC_GPDMA->DMACIntTCClear = 0x3;
AjK 0:0a841b89d614 92 LPC_GPDMA->DMACSoftSReq = 0xC;
AjK 0:0a841b89d614 93
AjK 0:0a841b89d614 94 /* Prep Channel1 to receive the incoming byte stream. */
AjK 0:0a841b89d614 95 LPC_GPDMACH1->DMACCSrcAddr = (uint32_t)&LPC_SSP0->DR;
AjK 0:0a841b89d614 96 LPC_GPDMACH1->DMACCDestAddr = (uint32_t)buffer;
AjK 0:0a841b89d614 97 LPC_GPDMACH1->DMACCLLI = 0;
AjK 0:0a841b89d614 98 LPC_GPDMACH1->DMACCControl = DMA_CHANNEL_TCIE | DMA_CHANNEL_DST_INC | (uint32_t)FLASH_PAGE_SIZE;
AjK 0:0a841b89d614 99
AjK 0:0a841b89d614 100 /* Prep Channel0 to send "don't care" bytes in order to clock out the data from the flash device. */
AjK 0:0a841b89d614 101 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)buffer; /* don't care data. */
AjK 0:0a841b89d614 102 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR;
AjK 0:0a841b89d614 103 LPC_GPDMACH0->DMACCLLI = 0;
AjK 0:0a841b89d614 104 LPC_GPDMACH0->DMACCControl = DMA_CHANNEL_TCIE | (uint32_t)FLASH_PAGE_SIZE;
AjK 0:0a841b89d614 105
AjK 0:0a841b89d614 106 /* Enable SSP0 DMA. */
AjK 0:0a841b89d614 107 LPC_SSP0->DMACR = 0x3;
AjK 0:0a841b89d614 108
AjK 0:0a841b89d614 109 /* Enable Channel0 */
AjK 0:0a841b89d614 110 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE |
AjK 0:0a841b89d614 111 DMA_CHANNEL_DST_PERIPHERAL_SSP0_TX |
AjK 0:0a841b89d614 112 DMA_TRANSFER_TYPE_M2P |
AjK 0:0a841b89d614 113 DMA_MASK_IE |
AjK 0:0a841b89d614 114 DMA_MASK_ITC;
AjK 0:0a841b89d614 115
AjK 0:0a841b89d614 116 /* Wait until at least one byte has arrived into the RX FIFO
AjK 0:0a841b89d614 117 and then start-up the Channel1 DMA to begin transferring them. */
AjK 0:0a841b89d614 118 while((LPC_SSP0->SR & (1UL << 2)) == 0);
AjK 0:0a841b89d614 119
AjK 0:0a841b89d614 120 /* Enable Channel1 */
AjK 0:0a841b89d614 121 LPC_GPDMACH1->DMACCConfig = DMA_CHANNEL_ENABLE |
AjK 0:0a841b89d614 122 DMA_CHANNEL_SRC_PERIPHERAL_SSP0_RX |
AjK 0:0a841b89d614 123 DMA_TRANSFER_TYPE_P2M |
AjK 0:0a841b89d614 124 DMA_MASK_IE |
AjK 0:0a841b89d614 125 DMA_MASK_ITC;
AjK 0:0a841b89d614 126
AjK 0:0a841b89d614 127 /* SSP0 CS line and "page_read_in_progress" flag are now
AjK 0:0a841b89d614 128 under DMA/SSP0 interrupt control. See the DMA ISR handlers
AjK 0:0a841b89d614 129 and SSP0 ISR handlers for more information. */
AjK 0:0a841b89d614 130
AjK 0:0a841b89d614 131 return 1;
AjK 0:0a841b89d614 132 }
AjK 0:0a841b89d614 133
AjK 0:0a841b89d614 134 /** flash_read_ssp0_irq
AjK 0:0a841b89d614 135 *
AjK 0:0a841b89d614 136 * Called by the SSP0 ISR handler.
AjK 0:0a841b89d614 137 */
AjK 0:0a841b89d614 138 int flash_read_ssp0_irq(void) {
AjK 0:0a841b89d614 139 if (page_read_in_progress) {
AjK 0:0a841b89d614 140 if (LPC_SSP0->MIS & (1UL << 3)) {
AjK 0:0a841b89d614 141 LPC_SSP0->IMSC &= ~(1UL << 3);
AjK 0:0a841b89d614 142 while(SSP0_IS_BUSY);
AjK 0:0a841b89d614 143 FLASH_CS_DEASSERT;
AjK 0:0a841b89d614 144 SSP0_release();
AjK 0:0a841b89d614 145 page_read_in_progress = false;
AjK 0:0a841b89d614 146 return 1;
AjK 0:0a841b89d614 147 }
AjK 0:0a841b89d614 148 }
AjK 0:0a841b89d614 149 return 0;
AjK 0:0a841b89d614 150 }
AjK 0:0a841b89d614 151
AjK 0:0a841b89d614 152 /* The following two functions are the DMA ISR handlers. They are
AjK 0:0a841b89d614 153 called from dma.c so see that module for more details. */
AjK 0:0a841b89d614 154
AjK 0:0a841b89d614 155 /** flash_read_dma0_irq
AjK 0:0a841b89d614 156 */
AjK 0:0a841b89d614 157 int flash_read_dma0_irq(int channel_number) {
AjK 0:0a841b89d614 158 if (page_read_in_progress) {
AjK 0:0a841b89d614 159 LPC_GPDMACH0->DMACCConfig = 0;
AjK 0:0a841b89d614 160 DMA_release_channel(0);
AjK 0:0a841b89d614 161 return 1;
AjK 0:0a841b89d614 162 }
AjK 0:0a841b89d614 163 return 0;
AjK 0:0a841b89d614 164 }
AjK 0:0a841b89d614 165
AjK 0:0a841b89d614 166 /** flash_read_dma1_irq
AjK 0:0a841b89d614 167 */
AjK 0:0a841b89d614 168 int flash_read_dma1_irq(int channel_number) {
AjK 0:0a841b89d614 169 if (page_read_in_progress) {
AjK 0:0a841b89d614 170 LPC_GPDMACH1->DMACCConfig = 0;
AjK 0:0a841b89d614 171 DMA_release_channel(1);
AjK 0:0a841b89d614 172 LPC_SSP0->IMSC = (1UL << 3);
AjK 0:0a841b89d614 173 return 1;
AjK 0:0a841b89d614 174 }
AjK 0:0a841b89d614 175 return 0;
AjK 0:0a841b89d614 176 }
AjK 0:0a841b89d614 177