⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at45.c

📁 此程序为GPS接收机的源码
💻 C
字号:
// AT45.c: Source file for accessing and controlling the Atmel AT45DB161B// serial flash chip // Copyright (C) 2005  Frank Mathew // Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 (June 1991).// See the "COPYING" file distributed with this software for more information.#include <cyg/kernel/kapi.h>#include "bsio.h"#include "at45.h"static unsigned char pad_buffer[60];unsigned charAT45_status(void){    unsigned char status = 0;        bsio_read(0, 0xD7000000, 8, 0, 0, &status, 1);        return status;}cyg_boolAT45_ready(void){    cyg_bool      flag   = 0;    unsigned char status = 0;    unsigned int  tries  = 0;        for (tries = 0; tries < 32768; tries++)    {        status = AT45_status();            if ((status & 0x80) != 0)        {            flag = 1;            break;        }    }        return flag;}cyg_boolAT45_init(void){    int i = 0;        for (i = 0; i < 60; i++)        pad_buffer[i] = 0;        return 0;}cyg_boolAT45_erase(void){    unsigned int  block_nr = 0;    cyg_bool      status   = 0;    for (block_nr=0; block_nr < 512; block_nr++)    {        if (!AT45_ready())        {            status = 1;            break;        }        bsio_write(0, (0x50 | (block_nr << 13)), 32, 0, 0, 0, 0);    }        return status;}#define AT45_PAGE_LENGTH    528#define AT45_PAGE_COUNT        4096#define AT45_BLOCK_COUNT    512// AT45_write_full_pages uses the page write-through command to// write entire pages at a time cyg_boolAT45_write_full_page(int  page_nr,                     char *write_buffer){    long int command        = 0x00000000;    cyg_bool status         = 0;        if (!AT45_ready())    {        status = 1;    }    else    {        command = 0x82000000                  | ((page_nr << 10) & 0x003FFC00);            status = bsio_write(0, command, 32,                            0, 0,                            write_buffer, AT45_PAGE_LENGTH);    }        return status;}// AT45_write_partial_page uses three commands to// write part of a single page: //     read a flash page into buffer #1//     write data into buffer #1//     write buffer #1 back to memory with erasecyg_boolAT45_write_partial_page(int  page_nr,                        int  page_offset,                        char *write_buffer,                        int  length){    long int command = 0x00000000;    cyg_bool status  = 0;    // Wait for the flash to be ready    if (!AT45_ready())    {        status = 1;    }    else    {        // Get the page data into buffer #1        command = 0x53000000                  | ((page_nr << 10) & 0x003FFC00);            status = bsio_write(0, command, 32,                            0, 0,                            0, 0);        // Write the data into buffer #1        if (!AT45_ready())        {            status = 1;        }        else        {            command = 0x84000000                      | (page_offset & 0x000003FF);                    status = bsio_write(0, command, 32,                                0, 0,                                write_buffer, length);            // Push buffer #1 back to the flash page            if (!AT45_ready())            {                status = 1;            }            else            {                command = 0x83000000                          | ((page_nr << 10) & 0x003FFC00);                            status = bsio_write(0, command, 32,                                    0, 0,                                    0, 0);            }        }    }        return status;}// AT45_write writes an arbitrary number of bytes to// an arbitrary set of pages in the flash chip//    the byte stream can start anywhere in a page and //    end anywhere in the same or other page.cyg_boolAT45_write(long int address, char *write_buffer, long int length){    int      page_nr               = 0;    int      starting_byte_in_page = 0;    int      current_write_length  = 0;    cyg_bool status                = 0;    while ((length > 0) && (status = 0))    {        page_nr = address / AT45_PAGE_LENGTH;        starting_byte_in_page = address - (page_nr * AT45_PAGE_LENGTH);        // If the address does not start at the beginning of a page        // then write it as a partial page        if (starting_byte_in_page > 0)        {            current_write_length = (AT45_PAGE_LENGTH                                    - starting_byte_in_page                                    + 1);            if (current_write_length > length)                current_write_length = length;                    status = AT45_write_partial_page(page_nr,                                             starting_byte_in_page,                                             write_buffer,                                             current_write_length);        }        else        if (length >= AT45_PAGE_LENGTH)        {            current_write_length = AT45_PAGE_LENGTH;            status = AT45_write_full_page(page_nr,                                          write_buffer);        }        else        {            current_write_length = length;            status = AT45_write_partial_page(page_nr,                                             0,                                             write_buffer,                                                current_write_length);        }                address      += current_write_length;        write_buffer += current_write_length;        length       -= current_write_length;    }        return status;}cyg_bool AT45_read(long int address, char *read_buffer, long int length){    int      max_read_length     = 1023;    int      current_read_length = 0;    long int command             = 0x00000000;    long int page_nr             = 0;    long int byte_in_page        = 0;    cyg_bool status              = 0;    while ((length > 0) && (status == 0))    {        if (!AT45_ready())        {            status = 1;        }        else        {            current_read_length = max_read_length;            if (length < max_read_length)                current_read_length = length;                page_nr = address / AT45_PAGE_LENGTH;            byte_in_page = address - (page_nr * AT45_PAGE_LENGTH);                    command = 0xE8000000                      | ((page_nr << 10) & 0x003FFC00)                      | (byte_in_page    & 0x000003FF);                status = bsio_read(0, command, 32,                               pad_buffer, 4,                               read_buffer, current_read_length);                address     += current_read_length;            read_buffer += current_read_length;            length      -= current_read_length;        }    }        return status;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -