![]() |
|
||||||||||||||
| . 网站首页 . 新闻 . 新品 . 方案 . 专访 . 活动 . DSP . EDA . 评测室 . 技术文库 . 会员区 . 商城 . 服务导航 . 邮购 . 资源 . | ||
|
||
|
|||||
| 移植测试好的C代码 | |||||
作者:61IC录入 文章来源:本站原创 点击数: 更新时间:2006-4-7 ![]() |
|||||
|
//CPU Mega16L @7.3728MHz //***************************************************************************** // // COPYRIGHT (c) ATMEL Norway, 1996-2001 // // The copyright to the document(s) herein is the property of // ATMEL Norway, Norway. // // The document(s) may be used and/or copied only with the written // permission from ATMEL Norway or in accordance with the terms and // conditions stipulated in the agreement/contract under which the // document(s) have been supplied. // //***************************************************************************** // // File........: DATAFLASH.C // // Author(s)...: ATMEL Norway // // Target(s)...: All AVRs with built-in HW SPI // // Description.: Functions to access the Atmel AT45Dxxx dataflash series // Supports 512Kbit - 64Mbit // // Revisions...: // // YYYYMMDD - VER. - COMMENT - SIGN. // // 20011017 - 1.00 - Beta release - RM // 20011017 - 0.10 - Generated file - RM // 20050403 port to avr-gcc/avr-libc - zlei // //***************************************************************************** // Includes #include <avr/io.h> #include <inttypes.h> #include <avr/pgmspace.h> #include "dataflash.h" // Constants //Look-up table for these sizes -> 512k, 1M, 2M, 4M, 8M, 16M, 32M, 64M const uint8_t DF_pagebits[] PROGMEM ={ 9, 9, 9, 9, 9, 10, 10, 11}; //index of internal page address bits //Look-up table for these sizes -> 512k, 1M, 2M, 4M, 8M, 16M, 32M, 64M const uint16_t DF_pagesize[] PROGMEM ={264,264, 264, 264, 264, 528, 528,1056}; //index of pagesizes // Globals unsigned char PageBits = 0; unsigned int PageSize = 0; // Functions /***************************************************************************** * * Function name : DF_SPI_init * * Returns : None * * Parameters : None * * Purpose : Sets up the HW SPI in Master mode, Mode 3 * Note -> Uses the SS line to control the DF CS-line. * ******************************************************************************/ void DF_SPI_init (void) { PORTB |= (1<<PB4) | (1<<PB5) | (1<<PB6) | (1<<PB7); DDRB |= (1<<DDB5) | (1<<DDB7) | (1<<DDB4); //Set MOSI, SCK AND SS as outputs SPSR = (1<<SPI2X); //SPI double speed settings SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (1<<CPOL); //Enable SPI in Master mode, mode 3, Fosc/4 } /***************************************************************************** * * Function name : DF_SPI_RW * * Returns : Byte read from SPI data register (any value) * * Parameters : Byte to be written to SPI data register (any value) * * Purpose : Read and writes one byte from/to SPI master * ******************************************************************************/ unsigned char DF_SPI_RW (unsigned char output) { unsigned char input; SPDR = output; //put byte 'output' in SPI data register while(!(SPSR & 0x80)); //wait for transfer complete, poll SPIF-flag input = SPDR; //read value in SPI data reg. return input; //return the byte clocked in from SPI slave } /***************************************************************************** * * Function name : Read_DF_status * * Returns : One status byte. Consult Dataflash datasheet for further * decoding info * * Parameters : None * * Purpose : Status info concerning the Dataflash is busy or not. * Status info concerning compare between buffer and flash page * Status info concerning size of actual device * ******************************************************************************/ unsigned char Read_DF_status (void) { unsigned char result,index_copy; DF_CS_DISABLE; //make sure to toggle CS signal in order DF_CS_ENABLE; //to reset dataflash command decoder result = DF_SPI_RW(StatusReg); //send status register read op-code result = DF_SPI_RW(0x00); //dummy write to get result index_copy = ((result & 0x38) >> 3); //get the size info from status register PageBits = pgm_read_byte(&DF_pagebits[index_copy]); //get number of internal page address bits from look-up table PageSize = pgm_read_word(&DF_pagesize[index_copy]); //get the size of the page (in bytes) return result; //return the read status register value } /***************************************************************************** * * Function name : Page_To_Buffer * * Returns : None * * Parameters : BufferNo -> Decides usage of either buffer 1 or 2 * PageAdr -> Address of page to be transferred to buffer * * Purpose : Transfers a page from flash to dataflash SRAM buffer * ******************************************************************************/ void Page_To_Buffer (unsigned int PageAdr, unsigned char BufferNo) { DF_CS_DISABLE; //make sure to toggle CS signal in order DF_CS_ENABLE; //to reset dataflash command decoder if (1 == BufferNo) //transfer flash page to buffer 1 { DF_SPI_RW(FlashToBuf1Transfer); //transfer to buffer 1 op-code DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address DF_SPI_RW((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address DF_SPI_RW(0x00); //don't cares } #ifdef USE_BUFFER2 else if (2 == BufferNo) //transfer flash page to buffer 2 { DF_SPI_RW(FlashToBuf2Transfer); //transfer to buffer 2 op-code DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address DF_SPI_RW((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address DF_SPI_RW(0x00); //don't cares } #endif DF_CS_DISABLE; //initiate the transfer DF_CS_ENABLE; while(!(Read_DF_status() & 0x80)); //monitor the status register, wait until busy-flag is high } /***************************************************************************** * * Function name : Buffer_Read_Byte * * Returns : One read byte (any value) * * Parameters : BufferNo -> Decides usage of either buffer 1 or 2 * IntPageAdr -> Internal page address * * Purpose : Reads one byte from one of the dataflash * internal SRAM buffers * ******************************************************************************/ unsigned char Buffer_Read_Byte (unsigned char BufferNo, unsigned int IntPageAdr) { unsigned char data; data='0'; DF_CS_DISABLE; //make sure to toggle CS signal in order DF_CS_ENABLE; //to reset dataflash command decoder if (1 == BufferNo) //read byte from buffer 1 { DF_SPI_RW(Buf1Read); //buffer 1 read op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address DF_SPI_RW(0x00); //don't cares data = DF_SPI_RW(0x00); //read byte } #ifdef USE_BUFFER2 else if (2 == BufferNo) //read byte from buffer 2 { DF_SPI_RW(Buf2Read); //buffer 2 read op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address DF_SPI_RW(0x00); //don't cares data = DF_SPI_RW(0x00); //read byte } #endif return data; //return the read data byte } /***************************************************************************** * * Function name : Buffer_Read_Str * * Returns : None * * Parameters : BufferNo -> Decides usage of either buffer 1 or 2 * IntPageAdr -> Internal page address * No_of_bytes -> Number of bytes to be read * *BufferPtr -> address of buffer to be used for read bytes * * Purpose : Reads one or more bytes from one of the dataflash * internal SRAM buffers, and puts read bytes into * buffer pointed to by *BufferPtr * ******************************************************************************/ void Buffer_Read_Str (unsigned char BufferNo, unsigned int IntPageAdr, unsigned int No_of_bytes, unsigned char *BufferPtr) { unsigned int i; DF_CS_DISABLE; //make sure to toggle CS signal in order DF_CS_ENABLE; //to reset dataflash command decoder if (1 == BufferNo) //read byte(s) from buffer 1 { DF_SPI_RW(Buf1Read); //buffer 1 read op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address DF_SPI_RW(0x00); //don't cares for( i=0; i<No_of_bytes; i++) { *(BufferPtr) = DF_SPI_RW(0x00); //read byte and put it in AVR buffer pointed to by *BufferPtr BufferPtr++; //point to next element in AVR buffer } } #ifdef USE_BUFFER2 else if (2 == BufferNo) //read byte(s) from buffer 2 { DF_SPI_RW(Buf2Read); //buffer 2 read op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address DF_SPI_RW(0x00); //don't cares for( i=0; i<No_of_bytes; i++) { *(BufferPtr) = DF_SPI_RW(0x00); //read byte and put it in AVR buffer pointed to by *BufferPtr BufferPtr++; //point to next element in AVR buffer } } #endif } /***************************************************************************** * * Function name : Buffer_Write_Enable * * Returns : None * * Parameters : IntPageAdr -> Internal page address to start writing from * BufferAdr -> Decides usage of either buffer 1 or 2 * * Purpose : Enables continous write functionality to one of the dataflash buffers * buffers. NOTE : User must ensure that CS goes high to terminate * this mode before accessing other dataflash functionalities * ******************************************************************************/ void Buffer_Write_Enable (unsigned char BufferNo, unsigned int IntPageAdr) { DF_CS_DISABLE; //make sure to toggle CS signal in order DF_CS_ENABLE; //to reset dataflash command decoder if (1 == BufferNo) //write enable to buffer 1 { DF_SPI_RW(Buf1Write); //buffer 1 write op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address } #ifdef USE_BUFFER2 else if (2 == BufferNo) //write enable to buffer 2 { DF_SPI_RW(Buf2Write); //buffer 2 write op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address } #endif } /***************************************************************************** * * Function name : Buffer_Write_Byte * * Returns : None * * Parameters : IntPageAdr -> Internal page address to write byte to * BufferAdr -> Decides usage of either buffer 1 or 2 * Data -> Data byte to be written * * Purpose : Writes one byte to one of the dataflash * internal SRAM buffers * ******************************************************************************/ void Buffer_Write_Byte (unsigned char BufferNo, unsigned int IntPageAdr, unsigned char Data) { DF_CS_DISABLE; //make sure to toggle CS signal in order DF_CS_ENABLE; //to reset dataflash command decoder if (1 == BufferNo) //write byte to buffer 1 { DF_SPI_RW(Buf1Write); //buffer 1 write op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address DF_SPI_RW(Data); //write data byte } #ifdef USE_BUFFER2 else if (2 == BufferNo) //write byte to buffer 2 { DF_SPI_RW(Buf2Write); //buffer 2 write op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address DF_SPI_RW(Data); //write data byte } #endif } /***************************************************************************** * * Function name : Buffer_Write_Str * * Returns : None * * Parameters : BufferNo -> Decides usage of either buffer 1 or 2 * IntPageAdr -> Internal page address * No_of_bytes -> Number of bytes to be written * *BufferPtr -> address of buffer to be used for copy of bytes * from AVR buffer to dataflash buffer 1 (or 2) * * Purpose : Copies one or more bytes to one of the dataflash * internal SRAM buffers from AVR SRAM buffer * pointed to by *BufferPtr * ******************************************************************************/ void Buffer_Write_Str (unsigned char BufferNo, unsigned int IntPageAdr, unsigned int No_of_bytes, unsigned char *BufferPtr) { unsigned int i; DF_CS_DISABLE; //make sure to toggle CS signal in order DF_CS_ENABLE; //to reset dataflash command decoder if (1 == BufferNo) //write byte(s) to buffer 1 { DF_SPI_RW(Buf1Write); //buffer 1 write op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address for( i=0; i<No_of_bytes; i++) { DF_SPI_RW(*(BufferPtr)); //write byte pointed at by *BufferPtr to dataflash buffer 1 location BufferPtr++; //point to next element in AVR buffer } } #ifdef USE_BUFFER2 else if (2 == BufferNo) //write byte(s) to buffer 2 { DF_SPI_RW(Buf2Write); //buffer 2 write op-code DF_SPI_RW(0x00); //don't cares DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address for( i=0; i<No_of_bytes; i++) { DF_SPI_RW(*(BufferPtr)); //write byte pointed at by *BufferPtr to dataflash buffer 2 location BufferPtr++; //point to next element in AVR buffer } } #endif } /***************************************************************************** * * Function name : Buffer_To_Page * * Returns : None * * Parameters : BufferAdr -> Decides usage of either buffer 1 or 2 * PageAdr -> Address of flash page to be programmed * * Purpose : Transfers a page from dataflash SRAM buffer to flash * ******************************************************************************/ void Buffer_To_Page (unsigned char BufferNo, unsigned int PageAdr) { DF_CS_DISABLE; //make sure to toggle CS signal in order DF_CS_ENABLE; //to reset dataflash command decoder if (1 == BufferNo) //program flash page from buffer 1 { DF_SPI_RW(Buf1ToFlashWE); //buffer 1 to flash with erase op-code DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address DF_SPI_RW((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address DF_SPI_RW(0x00); //don't cares } #ifdef USE_BUFFER2 else if (2 == BufferNo) //program flash page from buffer 2 { DF_SPI_RW(Buf2ToFlashWE); //buffer 2 to flash with erase op-code DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address DF_SPI_RW((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address DF_SPI_RW(0x00); //don't cares } #endif DF_CS_DISABLE; //initiate flash page programming DF_CS_ENABLE; while(!(Read_DF_status() & 0x80)); //monitor the status register, wait until busy-flag is high } /***************************************************************************** * * Function name : Cont_Flash_Read_Enable * * Returns : None * * Parameters : PageAdr -> Address of flash page where cont.read starts from * IntPageAdr -> Internal page address where cont.read starts from * * Purpose : Initiates a continuous read from a location in the DataFlash * ******************************************************************************/ void Cont_Flash_Read_Enable (unsigned int PageAdr, unsigned int IntPageAdr) { DF_CS_DISABLE; //make sure to toggle CS signal in order DF_CS_ENABLE; //to reset dataflash command decoder DF_SPI_RW(ContArrayRead); //Continuous Array Read op-code DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address DF_SPI_RW((unsigned char)((PageAdr << (PageBits - 8))+ (IntPageAdr>>8))); //lower part of page address and MSB of int.page adr. DF_SPI_RW((unsigned char)(IntPageAdr)); //LSB byte of internal page address DF_SPI_RW(0x00); //perform 4 dummy writes DF_SPI_RW(0x00); //in order to intiate DataFlash DF_SPI_RW(0x00); //address pointers DF_SPI_RW(0x00); } |
|||||
| 欢迎点击进入:TI德州中文网 (国内唯一针对TI应用的中文技术网站) 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| 没有相关文章 |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | | |||
|
|