Thông báo

Collapse
No announcement yet.

Thảo luận về ARM LPC 2138/2148

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Có anh nào làm giao tiếp MMC/SD dùng SPI1 cho lpc2148 chưa vậy, mình đang làm về cái này mà không biết vì sao ko debug được, còn chạy thì không có tín hiệu gì hết, nó bị lỗi gì trong file startup.s mà không chạy được. Anh em coi code của mình xem có cách nào sửa chữa không, giúp mình với nhé.
    code :http://www.mediafire.com/?zz2znwu4zom
    mmc.c

    //------------------------------------------------------------------------------
    // MMC.C 20060406 CHG
    //------------------------------------------------------------------------------
    // Simple read/write interface to MMC/SD cards.
    // Uses either SPI0 or SPI1 (SSP) on a Philips LPC2xxx ARM processor
    //------------------------------------------------------------------------------
    #include <LPC213X.H>
    #include "LPC214x.H" // LPC2148 MPU Register
    #include "mmc.h"
    #include "stdio.h"

    #define MMC_CMD_SIZE 6 // The SPI data is 8 bit long, the MMC use 48 bits, 6 bytes
    #define MMC_DATA_SIZE 512 // 512 bytes per block (sector)

    #define MAX_TIMEOUT 0xFF // just a raw number used for some of the timeout checks..

    // Returncodes not currently used/implemented
    //#define DATA_TOKEN_TIMEOUT 8
    //#define SELECT_CARD_TIMEOUT 9
    //#define SET_RELATIVE_ADDR_TIMEOUT 10



    #define RS 2
    #define RW 3
    #define EN 4
    #define BUSYBIT 17
    #define LCDPORT 14
    // khai bao cac ham

    void delay(unsigned long count1) ;
    int readpinport1(unsigned int portpin);
    int outpinport1(unsigned int portpin,unsigned int val);
    void WAIT_LCD(void);
    void write_nibble(unsigned int pos,unsigned char val);
    void WR_LCD( unsigned char TXT,unsigned int RSbit);//RSbit=0 cmd,=1 data
    void INT_LCD(void);
    void SET_POS(unsigned int pos);
    void CLR_LCD (void);
    void HOME_LCD (void);
    void WR_STR(unsigned char *str);
    //void putlcd(unsigned char *hienthi);
    /* end pototype section */
    void putlcd(unsigned char *hienthi)
    {

    IODIR0|= 15<<LCDPORT;//set output pin at LCD data bus
    IODIR0|=1<<RS; //set output
    IODIR0|=1<<RW; //set output
    IODIR0|=1<<EN; //set output
    INT_LCD();
    CLR_LCD();
    HOME_LCD();
    WR_STR(hienthi);

    }
    // cac function
    //-------------delay-------------------------
    void delay(unsigned long count1)
    {
    while(count1 > 0) {count1--;} // Loop Decrease Counter
    }


    //-------------read pin function-------------
    int readpinport1(unsigned int portpin)
    {
    unsigned long p;
    IODIR0&=~(1<<portpin); //set input
    p=IO0PIN; //doc trang thai port 0
    p=(p&(1<<portpin))>>portpin;// kiem tra bit p0.5
    return (p) ;
    }
    //----------------write pin------------------
    //out
    int outpinport1(unsigned int portpin,unsigned int val)
    {
    // IODIR1|=1<<portpin; //set output
    if (val)
    IOSET0|=1<<portpin;
    else
    IOCLR0|=1<<portpin;
    return (1) ;
    }
    //---------------write Nibble byte-----------------
    void write_nibble(unsigned int pos,unsigned char val)
    {
    unsigned long p;
    //IODIR1|=15<<pos;//set output pin
    p=IO0PIN;
    p=(p|15<<pos);
    p&= (val<<pos)|(~(15<<pos));
    //k=(val<<pos)|(~(15<<pos));
    //v= p&k;
    IO0PIN=p;

    //p&=(~(15<<pos))|(val<<pos) ;
    //IO1PIN=p;
    }
    //----------WAIT_LCD function----------------------
    void WAIT_LCD(void)
    {
    delay(100000);
    /*outpinport1(BUSYBIT,1);
    outpinport1(RW,1);
    outpinport1(EN,1);
    outpinport1(RS,0);
    while(readpinport1(BUSYBIT));
    outpinport1(EN,0);
    outpinport1(RW,0);*/
    }
    //----------write LCD Nibble Mode------------------
    void WR_LCD( unsigned char TXT,unsigned int RSbit)
    {
    unsigned int temp;
    outpinport1(RS,RSbit);
    outpinport1(RW,0);
    //write 4 bit high
    outpinport1(EN,1);
    temp=(TXT&0xF0)>>4;
    write_nibble(LCDPORT,temp);
    delay(10000);
    outpinport1(EN,0);
    //delay(10000);
    //write 4 bit low
    outpinport1(EN,1);
    temp=TXT&0x0F;
    write_nibble(LCDPORT,temp);
    delay(10000);
    outpinport1(EN,0);
    WAIT_LCD();

    }
    //---------------INT LCD Function----------------
    void INT_LCD(void)
    {
    //function set 8 col 2 row, 5x7 dot format,NIBBLE MODE
    WR_LCD(0x28,0);
    // Dislay ON/OFF CURSOR Shift
    // dislay ON, Cursor Underline on, cursor blink off
    WR_LCD(0x0E,0);
    // increment (dich fai) , Dislay Shift Off
    WR_LCD(0x06,0);
    }
    //-------------CLR LCD fuction---------------------
    void CLR_LCD (void)
    {
    WR_LCD(0x01,0);
    }
    //------------Home LCD function---------------------
    void HOME_LCD (void)
    {
    WR_LCD(0x02,0);
    }
    //-------- Set Pos function----------------------------
    void SET_POS(unsigned int pos)
    {
    if (pos<=15)
    WR_LCD(0x80+pos-1,0);
    else
    WR_LCD(0x80+pos+0x40-17,0);
    }
    //--------Write String to LCD------------------------
    void WR_STR(unsigned char *str)
    {
    while (*str != '\0')
    {
    WR_LCD(*str,1);
    ++str;
    }
    }

    //++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++
    //++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++
    //
    // Basic SPI functions to transport data to/from the card
    //
    //++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++
    //++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++

    //------------------------------------------------------------------------------
    // Send a buffer to the card
    //------------------------------------------------------------------------------
    static void sendMMCSPI(unsigned char *buf, unsigned int Length) {
    unsigned char Dummy;
    if ( Length == 0 )
    return;
    #ifdef SPI0
    while ( Length != 0 ) {
    S0SPDR = *buf;
    while ( !(S0SPSR & 0x80) );
    Length--;
    buf++;
    }
    Dummy=S0SPDR;
    #else
    while ( Length != 0 ) {
    // as long as TNF bit is set, TxFIFO is not full, I can write
    while (!(SSPSR & 0x02));
    SSPDR = *buf;
    // Wait until the Busy bit is cleared
    while (!(SSPSR & 0x04));
    Dummy = SSPDR; // Flush the RxFIFO
    Length--;
    buf++;
    }
    #endif
    return;
    }


    //------------------------------------------------------------------------------
    // SPI Receive Byte, receive one byte only, return Data byte
    // (used a lot to check the status from the card)
    //------------------------------------------------------------------------------
    static unsigned char receiveMMCSPI( void ) {
    unsigned char data;
    #ifdef SPI0
    // write dummy byte out to generate clock, then read data from MISO
    S0SPDR = 0xFF;
    // Wait until the Busy bit is cleared
    while (!(S0SPSR & 0x80));
    // Grab the received data
    data = S0SPDR;
    #else
    // write dummy byte out to generate clock, then read data from MISO
    SSPDR = 0xFF;
    // Wait until the Busy bit is cleared
    while (SSPSR & 0x10);
    // Grab the received data
    data = SSPDR;
    #endif
    return (data);
    }


    //------------------------------------------------------------------------------
    // SPI Receive, receive a number of bytes
    //------------------------------------------------------------------------------
    static void receiveBlockMMCSPI(unsigned char *buf, unsigned int Length) {
    unsigned int i;
    for (i = 0; i < Length; i++) {
    *buf = receiveMMCSPI();
    buf++;
    }
    return;
    }


    //-----------------------------------------------------------------------------
    // initMMCSPI()
    // Initializes the SPI port for the SD/MMC card
    // This function must be called before the initMMC() is called
    //-----------------------------------------------------------------------------
    void initMMCSPI(void ) {
    unsigned char i, Dummy;
    // Configure PIN connect block */
    // SSEL0/1 is NOT set to SSEL0/1, so enable/disable of the card is total manually done !

    #ifdef SPI0
    // Using SPI0 which has no FIFO
    PINSEL0|= 0x1500; //Enable SPI0 pins (except SSEL)
    IO_DIR |= CS;
    IO_SET = CS;

    S0SPCR = 0x00000020; // Configure as SPI Master
    S0SPCCR = 0x00000008; // Set bit timing
    Dummy = S0SPDR; // clear the RxFIFO
    #else
    // Using SPI1 (SSP port) which has a 8 byte FIFO
    SSPCR1 = 0x00; // SSP master (off) in normal mode */
    PINSEL1 |= 0x00A8; // Enable SPI1 pins (except SSEL)
    IO_DIR |= CS;
    IO_SET = CS;
    // Set PCLK 1/2 of CCLK
    VPBDIV = 0x02;
    // Set data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15
    SSPCR0 = 0x0707;
    // SSPCPSR clock prescale register, master mode, minimum divisor is 0x02
    SSPCPSR = 0x2;
    // Device select as master, SSP Enabled, normal operational mode
    SSPCR1 = 0x02;
    // clear the RxFIFO
    for ( i = 0; i < 8; i++ ) Dummy = SSPDR;
    #endif
    return;
    }


    //++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++
    //++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++
    //
    // SD/MMC functions
    //
    //++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++
    //++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++


    //------------------------------------------------------------------------------
    // Repeatedly reads the MMC until we get the response we want or timeout
    //------------------------------------------------------------------------------
    static int mmc_response( unsigned char response) {
    unsigned int count = 0xFFF;
    while((receiveMMCSPI() != response) && count) count--;
    if (count == 0)
    return 1; // Failure, loop was exited due to timeout
    else
    return 0; // Normal, loop was exited before timeout
    }


    //------------------------------------------------------------------------------
    // Repeatedly reads the MMC until we get a non-zero value (after
    // a zero value) indicating the write has finished and card is no
    // longer busy.
    //------------------------------------------------------------------------------
    static int mmc_wait_for_write_finish(void) {
    unsigned int count = 0xFFFF; // The delay is set to maximum considering the longest data block length to handle
    unsigned char result = 0;
    while((result == 0) && count) {
    result = receiveMMCSPI();
    count--;
    }
    if (count == 0)
    return 1; // Failure, loop was exited due to timeout
    else
    return 0; // Normal, loop was exited before timeout
    }


    //------------------------------------------------------------------------------
    // write a block of data based on the length that has been set
    // in the SET_BLOCKLEN command.
    // Send the WRITE_SINGLE_BLOCK command out first, check the
    // R1 response, then send the data start token(bit 0 to 0) followed by
    // the block of data. When the data write finishs, the response should come back
    // as 0xX5 bit 3 to 0 as 0101B, then another non-zero value indicating
    // that MMC card is in idle state again.
    //------------------------------------------------------------------------------
    int writeBlockMMC(unsigned int blocknum, unsigned char *Buffer) {
    unsigned char Status;
    unsigned char CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
    unsigned char MMCStatus = 0;

    IO_CLR = CS;
    // As we need to send a 32 bit address, we adjust the block number to 512 bytes alignment
    // and uses that as the address..
    blocknum <<= 9;
    CMD[1] = ((blocknum & 0xFF000000) >>24 );
    CMD[2] = ((blocknum & 0x00FF0000) >>16 );
    CMD[3] = ((blocknum & 0x0000FF00) >>8 );
    // send mmc CMD24(WRITE_SINGLE_BLOCK) to write the data to MMC card
    sendMMCSPI(CMD, MMC_CMD_SIZE );
    // if mmc_response returns 1 then we failed to get a 0x00 response
    if((mmc_response(0x00))==1) {
    MMCStatus = WRITE_BLOCK_TIMEOUT;
    IO_SET = CS;
    return MMCStatus;
    }
    // Set bit 0 to 0 which indicates the beginning of the data block
    CMD[0] = 0xFE;
    sendMMCSPI(CMD, 1);
    // send data
    sendMMCSPI(Buffer, MMC_DATA_SIZE );
    //Send dummy checksum
    // when the last check sum is sent, the response should come back
    // immediately. So, check the SPI FIFO MISO and make sure the status
    // return 0xX5, the bit 3 through 0 should be 0x05
    CMD[0] = 0xFF;
    CMD[1] = 0xFF;
    sendMMCSPI( CMD, 2 );
    Status = receiveMMCSPI();
    if ((Status & 0x0F) != 0x05) {
    MMCStatus = WRITE_BLOCK_FAIL;
    IO_SET = CS;
    return MMCStatus;
    }

    // if the status is already zero, the write hasn't finished yet and card is busy
    if(mmc_wait_for_write_finish()==1) {
    MMCStatus = WRITE_BLOCK_FAIL;
    IO_SET = CS;
    return MMCStatus;
    }

    IO_SET = CS;
    receiveMMCSPI();
    return 0;
    }


    //------------------------------------------------------------------------------
    // Reads a 512 Byte block from the MMC
    // Send READ_SINGLE_BLOCK command first, wait for response 0x00 followed by 0xFE.
    // Then call receiveBlockMMCSPI() to read the data block back followed by the checksum.
    //------------------------------------------------------------------------------
    int readBlockMMC(unsigned int blocknum, unsigned char *Buffer) {
    unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
    unsigned char MMCStatus = 0;

    IO_CLR = CS;
    // As we need to send a 32 bit address, we adjust the block number to 512 bytes alignment
    // and uses that as the address..
    blocknum <<= 9;
    CMD[1] = ((blocknum & 0xFF000000) >>24 );
    CMD[2] = ((blocknum & 0x00FF0000) >>16 );
    CMD[3] = ((blocknum & 0x0000FF00) >>8 );
    if (CMD[1]==0x20) {
    printf("Hit, CMD[1]=%i\n", CMD[1]);
    }

    // send MMC CMD17(READ_SINGLE_BLOCK) to read the data from MMC card
    sendMMCSPI(CMD, MMC_CMD_SIZE );
    // if mmc_response returns 1 then we failed to get a 0x00 response
    if((mmc_response(0x00))==1) {
    MMCStatus = READ_BLOCK_TIMEOUT;
    IO_SET = CS;
    return MMCStatus;
    }
    // wait for data token
    if((mmc_response(0xFE))==1) {
    MMCStatus = READ_BLOCK_DATA_TOKEN_MISSING;
    IO_SET = CS;
    printf("%i::readBlockMMC, blocknum=%i, CMD[1]=%i, CMD[2]=%i, CMD[3]=%i\n", __LINE__, blocknum, CMD[1],CMD[2],CMD[3]);
    return MMCStatus;
    }

    // Get the block of data based on the length
    receiveBlockMMCSPI(Buffer, MMC_DATA_SIZE);
    // CRC bytes that are not needed
    receiveMMCSPI();
    receiveMMCSPI();
    IO_SET = CS;
    receiveMMCSPI();
    return 0;
    }



    //------------------------------------------------------------------------------
    // Initialises the MMC into SPI mode and sets block size(512),
    // returns 0 on success (card found and initialized)
    //------------------------------------------------------------------------------
    int initMMC() {
    unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
    unsigned int i;
    unsigned char dummy=0xFF;
    unsigned char MMCStatus = 0;

    IO_SET = CS;
    // initialise the MMC card into SPI mode by sending 80 clks
    for(i=0; i<10; i++) sendMMCSPI( &dummy, 1 );
    IO_CLR = CS;

    // send CMD0(RESET or GO_IDLE_STATE) command, all the arguments are 0x00 for the reset command, precalculated checksum
    sendMMCSPI( CMD, MMC_CMD_SIZE );
    // if = 1 then there was a timeout waiting for 0x01 from the MMC
    if(mmc_response(0x01) == 1) {
    MMCStatus = IDLE_STATE_TIMEOUT;
    IO_SET = CS;
    return MMCStatus;
    }
    // Send some dummy clocks after GO_IDLE_STATE
    IO_SET = CS;
    receiveMMCSPI();

    IO_CLR = CS;
    // must keep sending command until zero response
    i = MAX_TIMEOUT;
    do {
    // send mmc CMD1(SEND_OP_COND) to bring out of idle state
    // all the arguments are 0x00 for command one
    CMD[0] = 0x41;
    CMD[5] = 0xFF;
    sendMMCSPI( CMD, MMC_CMD_SIZE );
    i--;
    } while ((mmc_response(0x00) != 0) && (i>0));
    // timeout waiting for 0x00 from the MMC
    if (i == 0) {
    MMCStatus = OP_COND_TIMEOUT;
    IO_SET = CS;
    return MMCStatus;
    }
    // Send some dummy clocks after SEND_OP_COND
    IO_SET = CS;
    receiveMMCSPI();

    IO_CLR = CS;
    // send MMC CMD16(SET_BLOCKLEN) to set the block length
    CMD[0] = 0x50;
    CMD[1] = 0x00; // 4 bytes from here is the block length
    // LSB is first
    // 00 00 00 10 set to 16 bytes
    // 00 00 02 00 set to 512 bytes
    CMD[2] = 0x00;
    // high block length bits - 512 bytes
    CMD[3] = 0x02;
    // low block length bits
    CMD[4] = 0x00;
    // checksum is no longer required but we always send 0xFF
    CMD[5] = 0xFF;
    sendMMCSPI(CMD, MMC_CMD_SIZE);
    if((mmc_response(0x00))==1) {
    MMCStatus = SET_BLOCKLEN_TIMEOUT;
    IO_SET = CS;
    return MMCStatus;
    }
    IO_SET = CS;
    receiveMMCSPI();
    return 0;
    }
    int main()
    {
    unsigned char *buf;
    unsigned char *str;
    str = "ky thuat may ";
    initMMC();
    writeBlockMMC(100,str);
    readBlockMMC(100, buf);
    putlcd(buf);

    }
    mmc.h
    //-----------------------------------------------------------------------------
    // MMC.H 20060407 CHG
    //-----------------------------------------------------------------------------
    // Simple read/write interface to MMC/SD cards.
    // Uses either SPI0 or SPI1 (SSP) on a Philips LPC2xxx ARM processor
    //-----------------------------------------------------------------------------
    #ifndef _MMC_H_
    #define _MMC_H_


    #define IDLE_STATE_TIMEOUT 1
    #define OP_COND_TIMEOUT 2
    #define SET_BLOCKLEN_TIMEOUT 3
    #define WRITE_BLOCK_TIMEOUT 4
    #define WRITE_BLOCK_FAIL 5
    #define READ_BLOCK_TIMEOUT 6
    #define READ_BLOCK_DATA_TOKEN_MISSING 7


    //-----------------------------------------------------------------------------
    // Define I/O pins for the interface
    //-----------------------------------------------------------------------------
    #define IO_DIR IODIR0 // The GPIO registers used for accessing the CS pin to the SD Card
    #define IO_SET IOSET0
    #define IO_CLR IOCLR0

    // Educationboard from Embedded Artists
    #define CS (1<<20) // P0.11 is CS

    // LPC2148 Small board on prototype board from Embedded Artists
    //#define CS (1<<22) // P0.22 is CS

    // Keil MCB2140
    //#define CS (1<<20) // P0.20 is CS



    //-----------------------------------------------------------------------------
    // Define which SPI port to use
    //-----------------------------------------------------------------------------
    #define SPI1 // Remove this to use SPI1 (SSP) port instead


    //------------------------------------------------------------------------------
    // Reads a 512 Byte block from the MMC
    // Send READ_SINGLE_BLOCK command first, wait for response 0x00 followed by 0xFE.
    // Then call receiveBlockMMCSPI() to read the data block back followed by the checksum.
    //------------------------------------------------------------------------------
    int readBlockMMC(unsigned int blocknum, unsigned char *Buffer);

    //------------------------------------------------------------------------------
    // write a block of data based on the length that has been set
    // in the SET_BLOCKLEN command.
    // Send the WRITE_SINGLE_BLOCK command out first, check the
    // R1 response, then send the data start token(bit 0 to 0) followed by
    // the block of data. When the data write finishs, the response should come back
    // as 0xX5 bit 3 to 0 as 0101B, then another non-zero value indicating
    // that MMC card is in idle state again.
    //------------------------------------------------------------------------------
    int writeBlockMMC(unsigned int blocknum, unsigned char *Buffer);

    //-----------------------------------------------------------------------------
    // initMMCSPI()
    // Initializes the SPI port for the SD/MMC card
    // This function must be called before the initMMC() is called
    //-----------------------------------------------------------------------------
    void initMMCSPI(void);

    //------------------------------------------------------------------------------
    // Initialises the MMC into SPI mode and sets block size(512),
    // returns 0 on success (card found and initialized)
    //------------------------------------------------------------------------------
    int initMMC(void);

    #endif

    startup.s
    ;/************************************************** ***************************/
    ;/* STARTUP.S: Startup file for Philips LPC2000 */
    ;/************************************************** ***************************/
    ;/* <<< Use Configuration Wizard in Context Menu >>> */
    ;/************************************************** ***************************/
    ;/* This file is part of the uVision/ARM development tools. */
    ;/* Copyright (c) 2005-2007 Keil Software. All rights reserved. */
    ;/* This software may only be used under the terms of a valid, current, */
    ;/* end user licence from KEIL for a compatible version of KEIL software */
    ;/* development tools. Nothing else gives you the right to use this software. */
    ;/************************************************** ***************************/


    ;/*
    ; * The STARTUP.S code is executed after CPU Reset. This file may be
    ; * translated with the following SET symbols. In uVision these SET
    ; * symbols are entered under Options - ASM - Define.
    ; *
    ; * REMAP: when set the startup code initializes the register MEMMAP
    ; * which overwrites the settings of the CPU configuration pins. The
    ; * startup and interrupt vectors are remapped from:
    ; * 0x00000000 default setting (not remapped)
    ; * 0x80000000 when EXTMEM_MODE is used
    ; * 0x40000000 when RAM_MODE is used
    ; *
    ; * EXTMEM_MODE: when set the device is configured for code execution
    ; * from external memory starting at address 0x80000000.
    ; *
    ; * RAM_MODE: when set the device is configured for code execution
    ; * from on-chip RAM starting at address 0x40000000.
    ; *
    ; * EXTERNAL_MODE: when set the PIN2SEL values are written that enable
    ; * the external BUS at startup.
    ; */


    ; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs

    Mode_USR EQU 0x10
    Mode_FIQ EQU 0x11
    Mode_IRQ EQU 0x12
    Mode_SVC EQU 0x13
    Mode_ABT EQU 0x17
    Mode_UND EQU 0x1B
    Mode_SYS EQU 0x1F

    I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
    F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled


    ;// <h> Stack Configuration (Stack Sizes in Bytes)
    ;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
    ;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
    ;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
    ;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
    ;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
    ;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
    ;// </h>

    UND_Stack_Size EQU 0x00000000
    SVC_Stack_Size EQU 0x00000008
    ABT_Stack_Size EQU 0x00000000
    FIQ_Stack_Size EQU 0x00000000
    IRQ_Stack_Size EQU 0x00000080
    USR_Stack_Size EQU 0x00000400

    ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
    FIQ_Stack_Size + IRQ_Stack_Size)

    AREA STACK, NOINIT, READWRITE, ALIGN=3

    Stack_Mem SPACE USR_Stack_Size
    __initial_sp SPACE ISR_Stack_Size

    Stack_Top


    ;// <h> Heap Configuration
    ;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
    ;// </h>

    Heap_Size EQU 0x00000000

    AREA HEAP, NOINIT, READWRITE, ALIGN=3
    __heap_base
    Heap_Mem SPACE Heap_Size
    __heap_limit


    ; VPBDIV definitions
    VPBDIV EQU 0xE01FC100 ; VPBDIV Address

    ;// <e> VPBDIV Setup
    ;// <i> Peripheral Bus Clock Rate
    ;// <o1.0..1> VPBDIV: VPB Clock
    ;// <0=> VPB Clock = CPU Clock / 4
    ;// <1=> VPB Clock = CPU Clock
    ;// <2=> VPB Clock = CPU Clock / 2
    ;// <o1.4..5> XCLKDIV: XCLK Pin
    ;// <0=> XCLK Pin = CPU Clock / 4
    ;// <1=> XCLK Pin = CPU Clock
    ;// <2=> XCLK Pin = CPU Clock / 2
    ;// </e>
    VPBDIV_SETUP EQU 0
    VPBDIV_Val EQU 0x00000000


    ; Phase Locked Loop (PLL) definitions
    PLL_BASE EQU 0xE01FC080 ; PLL Base Address
    PLLCON_OFS EQU 0x00 ; PLL Control Offset
    PLLCFG_OFS EQU 0x04 ; PLL Configuration Offset
    PLLSTAT_OFS EQU 0x08 ; PLL Status Offset
    PLLFEED_OFS EQU 0x0C ; PLL Feed Offset
    PLLCON_PLLE EQU (1<<0) ; PLL Enable
    PLLCON_PLLC EQU (1<<1) ; PLL Connect
    PLLCFG_MSEL EQU (0x1F<<0) ; PLL Multiplier
    PLLCFG_PSEL EQU (0x03<<5) ; PLL Divider
    PLLSTAT_PLOCK EQU (1<<10) ; PLL Lock Status

    ;// <e> PLL Setup
    ;// <o1.0..4> MSEL: PLL Multiplier Selection
    ;// <1-32><#-1>
    ;// <i> M Value
    ;// <o1.5..6> PSEL: PLL Divider Selection
    ;// <0=> 1 <1=> 2 <2=> 4 <3=> 8
    ;// <i> P Value
    ;// </e>
    PLL_SETUP EQU 1
    PLLCFG_Val EQU 0x00000024


    ; Memory Accelerator Module (MAM) definitions
    MAM_BASE EQU 0xE01FC000 ; MAM Base Address
    MAMCR_OFS EQU 0x00 ; MAM Control Offset
    MAMTIM_OFS EQU 0x04 ; MAM Timing Offset

    ;// <e> MAM Setup
    ;// <o1.0..1> MAM Control
    ;// <0=> Disabled
    ;// <1=> Partially Enabled
    ;// <2=> Fully Enabled
    ;// <i> Mode
    ;// <o2.0..2> MAM Timing
    ;// <0=> Reserved <1=> 1 <2=> 2 <3=> 3
    ;// <4=> 4 <5=> 5 <6=> 6 <7=> 7
    ;// <i> Fetch Cycles
    ;// </e>
    MAM_SETUP EQU 1
    MAMCR_Val EQU 0x00000002
    MAMTIM_Val EQU 0x00000004


    ; External Memory Controller (EMC) definitions
    EMC_BASE EQU 0xFFE00000 ; EMC Base Address
    BCFG0_OFS EQU 0x00 ; BCFG0 Offset
    BCFG1_OFS EQU 0x04 ; BCFG1 Offset
    BCFG2_OFS EQU 0x08 ; BCFG2 Offset
    BCFG3_OFS EQU 0x0C ; BCFG3 Offset

    ;// <e> External Memory Controller (EMC)
    EMC_SETUP EQU 0

    ;// <e> Bank Configuration 0 (BCFG0)
    ;// <o1.0..3> IDCY: Idle Cycles <0-15>
    ;// <o1.5..9> WST1: Wait States 1 <0-31>
    ;// <o1.11..15> WST2: Wait States 2 <0-31>
    ;// <o1.10> RBLE: Read Byte Lane Enable
    ;// <o1.26> WP: Write Protect
    ;// <o1.27> BM: Burst ROM
    ;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
    ;// <2=> 32-bit <3=> Reserved
    ;// </e>
    BCFG0_SETUP EQU 0
    BCFG0_Val EQU 0x0000FBEF

    ;// <e> Bank Configuration 1 (BCFG1)
    ;// <o1.0..3> IDCY: Idle Cycles <0-15>
    ;// <o1.5..9> WST1: Wait States 1 <0-31>
    ;// <o1.11..15> WST2: Wait States 2 <0-31>
    ;// <o1.10> RBLE: Read Byte Lane Enable
    ;// <o1.26> WP: Write Protect
    ;// <o1.27> BM: Burst ROM
    ;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
    ;// <2=> 32-bit <3=> Reserved
    ;// </e>
    BCFG1_SETUP EQU 0
    BCFG1_Val EQU 0x0000FBEF

    ;// <e> Bank Configuration 2 (BCFG2)
    ;// <o1.0..3> IDCY: Idle Cycles <0-15>
    ;// <o1.5..9> WST1: Wait States 1 <0-31>
    ;// <o1.11..15> WST2: Wait States 2 <0-31>
    ;// <o1.10> RBLE: Read Byte Lane Enable
    ;// <o1.26> WP: Write Protect
    ;// <o1.27> BM: Burst ROM
    ;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
    ;// <2=> 32-bit <3=> Reserved
    ;// </e>
    BCFG2_SETUP EQU 0
    BCFG2_Val EQU 0x0000FBEF

    ;// <e> Bank Configuration 3 (BCFG3)
    ;// <o1.0..3> IDCY: Idle Cycles <0-15>
    ;// <o1.5..9> WST1: Wait States 1 <0-31>
    ;// <o1.11..15> WST2: Wait States 2 <0-31>
    ;// <o1.10> RBLE: Read Byte Lane Enable
    ;// <o1.26> WP: Write Protect
    ;// <o1.27> BM: Burst ROM
    ;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
    ;// <2=> 32-bit <3=> Reserved
    ;// </e>
    BCFG3_SETUP EQU 0
    BCFG3_Val EQU 0x0000FBEF

    ;// </e> End of EMC


    ; External Memory Pins definitions
    PINSEL2 EQU 0xE002C014 ; PINSEL2 Address
    PINSEL2_Val EQU 0x0E6149E4 ; CS0..3, OE, WE, BLS0..3,
    ; D0..31, A2..23, JTAG Pins


    PRESERVE8


    ; Area Definition and Entry Point
    ; Startup Code must be linked first at Address at which it expects to run.

    AREA RESET, CODE, READONLY
    ARM


    ; Exception Vectors
    ; Mapped to Address 0.
    ; Absolute addressing mode must be used.
    ; Dummy Handlers are implemented as infinite loops which can be modified.

    Vectors LDR PC, Reset_Addr
    LDR PC, Undef_Addr
    LDR PC, SWI_Addr
    LDR PC, PAbt_Addr
    LDR PC, DAbt_Addr
    NOP ; Reserved Vector
    ; LDR PC, IRQ_Addr
    LDR PC, [PC, #-0x0FF0] ; Vector from VicVectAddr
    LDR PC, FIQ_Addr

    Reset_Addr DCD Reset_Handler
    Undef_Addr DCD Undef_Handler
    SWI_Addr DCD SWI_Handler
    PAbt_Addr DCD PAbt_Handler
    DAbt_Addr DCD DAbt_Handler
    DCD 0 ; Reserved Address
    IRQ_Addr DCD IRQ_Handler
    FIQ_Addr DCD FIQ_Handler

    Undef_Handler B Undef_Handler
    SWI_Handler B SWI_Handler
    PAbt_Handler B PAbt_Handler
    DAbt_Handler B DAbt_Handler
    IRQ_Handler B IRQ_Handler
    FIQ_Handler B FIQ_Handler


    ; Reset Handler

    EXPORT Reset_Handler
    Reset_Handler


    ; Setup External Memory Pins
    IF EF:EXTERNAL_MODE
    LDR R0, =PINSEL2
    LDR R1, =PINSEL2_Val
    STR R1, [R0]
    ENDIF


    ; Setup External Memory Controller
    IF EMC_SETUP <> 0
    LDR R0, =EMC_BASE

    IF BCFG0_SETUP <> 0
    LDR R1, =BCFG0_Val
    STR R1, [R0, #BCFG0_OFS]
    ENDIF

    IF BCFG1_SETUP <> 0
    LDR R1, =BCFG1_Val
    STR R1, [R0, #BCFG1_OFS]
    ENDIF

    IF BCFG2_SETUP <> 0
    LDR R1, =BCFG2_Val
    STR R1, [R0, #BCFG2_OFS]
    ENDIF

    IF BCFG3_SETUP <> 0
    LDR R1, =BCFG3_Val
    STR R1, [R0, #BCFG3_OFS]
    ENDIF

    ENDIF ; EMC_SETUP


    ; Setup VPBDIV
    IF VPBDIV_SETUP <> 0
    LDR R0, =VPBDIV
    LDR R1, =VPBDIV_Val
    STR R1, [R0]
    ENDIF


    ; Setup PLL
    IF PLL_SETUP <> 0
    LDR R0, =PLL_BASE
    MOV R1, #0xAA
    MOV R2, #0x55

    ; Configure and Enable PLL
    MOV R3, #PLLCFG_Val
    STR R3, [R0, #PLLCFG_OFS]
    MOV R3, #PLLCON_PLLE
    STR R3, [R0, #PLLCON_OFS]
    STR R1, [R0, #PLLFEED_OFS]
    STR R2, [R0, #PLLFEED_OFS]

    ; Wait until PLL Locked
    PLL_Loop LDR R3, [R0, #PLLSTAT_OFS]
    ANDS R3, R3, #PLLSTAT_PLOCK
    BEQ PLL_Loop

    ; Switch to PLL Clock
    MOV R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)
    STR R3, [R0, #PLLCON_OFS]
    STR R1, [R0, #PLLFEED_OFS]
    STR R2, [R0, #PLLFEED_OFS]
    ENDIF ; PLL_SETUP


    ; Setup MAM
    IF MAM_SETUP <> 0
    LDR R0, =MAM_BASE
    MOV R1, #MAMTIM_Val
    STR R1, [R0, #MAMTIM_OFS]
    MOV R1, #MAMCR_Val
    STR R1, [R0, #MAMCR_OFS]
    ENDIF ; MAM_SETUP


    ; Memory Mapping (when Interrupt Vectors are in RAM)
    MEMMAP EQU 0xE01FC040 ; Memory Mapping Control
    IF EF:REMAP
    LDR R0, =MEMMAP
    IF EF:EXTMEM_MODE
    MOV R1, #3
    ELIF EF:RAM_MODE
    MOV R1, #2
    ELSE
    MOV R1, #1
    ENDIF
    STR R1, [R0]
    ENDIF


    ; Initialise Interrupt System
    ; ...


    ; Setup Stack for each mode

    LDR R0, =Stack_Top

    ; Enter Undefined Instruction Mode and set its Stack Pointer
    MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
    MOV SP, R0
    SUB R0, R0, #UND_Stack_Size

    ; Enter Abort Mode and set its Stack Pointer
    MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
    MOV SP, R0
    SUB R0, R0, #ABT_Stack_Size

    ; Enter FIQ Mode and set its Stack Pointer
    MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
    MOV SP, R0
    SUB R0, R0, #FIQ_Stack_Size

    ; Enter IRQ Mode and set its Stack Pointer
    MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
    MOV SP, R0
    SUB R0, R0, #IRQ_Stack_Size

    ; Enter Supervisor Mode and set its Stack Pointer
    MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
    MOV SP, R0
    SUB R0, R0, #SVC_Stack_Size

    ; Enter User Mode and set its Stack Pointer
    MSR CPSR_c, #Mode_USR
    IF EF:__MICROLIB

    EXPORT __initial_sp

    ELSE

    MOV SP, R0
    SUB SL, SP, #USR_Stack_Size

    ENDIF


    ; Enter the C code

    IMPORT __main
    LDR R0, =__main
    BX R0


    IF EF:__MICROLIB

    EXPORT __heap_base
    EXPORT __heap_limit

    ELSE
    ; User Initial Stack & Heap
    AREA |.text|, CODE, READONLY

    IMPORT __use_two_region_memory
    EXPORT __user_initial_stackheap
    __user_initial_stackheap

    LDR R0, = Heap_Mem
    LDR R1, =(Stack_Mem + USR_Stack_Size)
    LDR R2, = (Heap_Mem + Heap_Size)
    LDR R3, = Stack_Mem
    BX LR
    ENDIF


    END
    |

    Comment


    • đây là sơ đồ kết nối MMC/SD của mình
      http://www.mediafire.com/imageview.p...ey=mlyyzyqhm0q
      |

      Comment


      • Em chân ướt chân ráo nhảy vào ARM_Nhận cái đề tài KHSV.Bây giờ vắt chân lên cẳng mà chạy.Thấy các bác post bài về LPC 2148 em đã quá-Mấy pro xin cứ post bài nhiều vào nha.Em đang chờ mờ mắt đây_keke.Cám ơn các bác nhiều lắm.


        Add: 97 Quán Nam - Lê Chân - Hải Phòng.
        Tel: 031 518648 Phone: 0904 283 505

        Comment


        • Keke_Cái flashMagic khi nạp sao nó lại tự thoát khỏi CT nhỉ(Khi xóa hay nạp thì đều như vậy)_Em cũng mới chơi cái con ARM nên chưa xài cái flashMagic này bao giờ_Các bác cho em ý kiến_Phần mềm có vấn đề hay chip có vấn đề_chip mà bị sao thì em toi.Mà sao LPC2148 mới cấp nguồn mà đã ấm ấm rồi hả mấy pro_Có sao ko nhỉ???Mấy dòng khác đâu có thế nhỉ??


          Add: 97 Quán Nam - Lê Chân - Hải Phòng.
          Tel: 031 518648 Phone: 0904 283 505

          Comment


          • Em nạp với flashmagic thì gặp lỗi này_mời các pro chỉ giúp.
            Attached Files


            Add: 97 Quán Nam - Lê Chân - Hải Phòng.
            Tel: 031 518648 Phone: 0904 283 505

            Comment


            • Trời ơi!Đã 2 ngày rồi mà ko thấy ai hồi âm thế nhỉ???????/Ý tưởng đưa ARM ra khỏi mục các họ khác của mấy pro chắc ko đc rồi.Huhu!


              Add: 97 Quán Nam - Lê Chân - Hải Phòng.
              Tel: 031 518648 Phone: 0904 283 505

              Comment


              • Bạn thử xem lại xem có đúng là COM8 ko, xem lại mạch có vấn đề gì ko, thử giảm baud rate xuống 1200 xem sao... (theo link nó chỉ ra đó http://forum.flashmagictool.com/index.php?topic=3628.0 )

                Mình dùng linux, cắm cái dây usb to com vào thì nó attached to ttyUSB1, dùng GTKterm test tín hiệu TX,RX,DTR,RTS đều ok, nhưng vào flash magic thì ko biết chọn com port nào, đã thử chọn đủ 32 com port mà ko đúng cái nào , toàn báo "Unable to communicate"
                Nhờ các cao nhân chỉ giúp với
                Phạm Minh Tuấn

                (+84) 982006467

                Comment


                • Đã giải quyết được:

                  Nguyên văn bởi quocthai_bk
                  http://karuppuswamy.com/wordpress/2008/11/20/flashmagic-on-linux-using-wine/
                  Thanks anh Quốc Thái
                  Phạm Minh Tuấn

                  (+84) 982006467

                  Comment


                  • Tình hình là mình dùng keil, dịch cái code nháy led của hbaocr ở post #8 page 1, nạp vào verify ok hết, mà led ko nháy, đo điện áp chân output của LPC2148 thì có chân là 0V, có chân 1.8V, ko biết vdk có chạy ko nữa, vậy là sao nhỉ?
                    Có cần config cái gì ở file startup ko?
                    Phạm Minh Tuấn

                    (+84) 982006467

                    Comment


                    • ai có bài giới thiệu vể LPC2138 ko?Nếu có thì post lên cho mình với.Thanks^^
                      |

                      Comment


                      • Chào cả nhà, em cũng mới bắt đầu tập tành với ARM, lý thuyết được chút ít rồi nên giờ muốn lọ mọ thực hành, em đã cài Keil CARM xong xuôi (*** đầy đủ), nhưng khi xây dựng project thì em còn lơ mơ cái phần add file thư viện vào project, dùng code mẫu thì bị báo lỗi là Error: failed to execute 'C:\Keil\ARM\BIN\ARM\bin\ARM\BIN\CA'. Các bác giúp em với được không ạ, nếu có hình minh họa thì càng tốt, em hơi tham lam tí

                        Comment


                        • Nguyên văn bởi hvhien Xem bài viết
                          Chào cả nhà, em cũng mới bắt đầu tập tành với ARM, lý thuyết được chút ít rồi nên giờ muốn lọ mọ thực hành, em đã cài Keil CARM xong xuôi (*** đầy đủ), nhưng khi xây dựng project thì em còn lơ mơ cái phần add file thư viện vào project, dùng code mẫu thì bị báo lỗi là Error: failed to execute 'C:\Keil\ARM\BIN\ARM\bin\ARM\BIN\CA'. Các bác giúp em với được không ạ, nếu có hình minh họa thì càng tốt, em hơi tham lam tí
                          vì bạn sử dụng phiên bản keil không thích hợp với cái sample project của bạn.Thử cài lại version khác đi! Vì Keil có 2 phiên bản ( từ 3.05a trở về trước sử dụng complier : CARM, từ 3.05a trở đi sử dụng trình complier là realview)! Cho nên nếu bạn đang sử dụng phiên bản keil mới đây thì sẽ ko biên dịch được project viết bằng CARM ; và ngược lại nếu bạn sài version "cũ" thì sẽ ko build duoc project viết bằng KEIL "mới" dùng REALVIEW

                          Comment


                          • Nguyên văn bởi hbaocr Xem bài viết
                            vì bạn sử dụng phiên bản keil không thích hợp với cái sample project của bạn.Thử cài lại version khác đi! Vì Keil có 2 phiên bản ( từ 3.05a trở về trước sử dụng complier : CARM, từ 3.05a trở đi sử dụng trình complier là realview)! Cho nên nếu bạn đang sử dụng phiên bản keil mới đây thì sẽ ko biên dịch được project viết bằng CARM ; và ngược lại nếu bạn sài version "cũ" thì sẽ ko build duoc project viết bằng KEIL "mới" dùng REALVIEW
                            Em cũng đã nghĩ đến việc này, em đang cài bản 3.6, em tưởng trình dich tương ứng được cài cùng khi ta cài đặt Keil chứ nhỉ. À thế còn cái món add các file thư viện thì sao hả bác, ví như làm sao để em có thư viện lpc214x.h, rồi có add nó theo quy cách như khi add file soạn code ko ạ, cả file startup.c nữa. Bác chỉ giúp em cái

                            Comment


                            • các bác cho em hỏi trong dòng lệnh ví dụ như sau :
                              void OUTPORT0(unsigned int A)
                              {
                              unsigned long temp;
                              temp |= 1<<(A+1) ;
                              ................


                              }

                              thì việc tính 1<<(A+1) được thực hiện trong chương trình biên dịch hay trong VDK
                              tức là nó có làm mất thời gian của VDK ko

                              Comment


                              • Nguyên văn bởi qkhanh Xem bài viết
                                các bác cho em hỏi trong dòng lệnh ví dụ như sau :
                                void OUTPORT0(unsigned int A)
                                {
                                unsigned long temp;
                                temp |= 1<<(A+1) ;
                                ................


                                }

                                thì việc tính 1<<(A+1) được thực hiện trong chương trình biên dịch hay trong VDK
                                tức là nó có làm mất thời gian của VDK ko
                                Theo mình nó sẽ thực hiện trong VDK, nếu khi nào A là hằng const thì trình biên dịch sẽ tự động tính giá trị 1<<(A+1).

                                Or call me 0903911109

                                Comment

                                Về tác giả

                                Collapse

                                emdaikho Tìm hiểu thêm về emdaikho

                                Bài viết mới nhất

                                Collapse

                                Đang tải...
                                X