Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91SAM9261 и SPI DataFlash
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Morfko
Кто-нибудь может выложить пример инициализации SPI и проверку статуса для AT45?

Делал связь с AT45DB161 на SAM7X256 и никаких проблем не было, а здесь не получается почему-то. Может подводные камни какие-то существуют...

Спасибо!
DpInRock
Код
unsigned char At45Status(void)
{
unsigned char a;
Flash_Send(0xD7,0);
a=Flash_Send(0,LAST);
if ((a&1)==0) return(a&0x80);
At45error=1;//error status byte
return(1);
}


Код
void SPIConfig(void)
{


AT91C_BASE_SPI0->SPI_CR=0x82;//disable and reset
//AT91C_BASE_SPI1->SPI_CR=0x82;//disable and reset

AT91C_BASE_SPI0->SPI_MR=0x0a0f0013;//master
//AT91C_BASE_SPI1->SPI_MR=0x0a0f0013;//master

//SerialFlash 25 Mhz 8 bit
AT91C_BASE_SPI0->SPI_CSR[0]=0x00220F0A;

//SSM2602 14 MHz 16 bit
AT91C_BASE_SPI0->SPI_CSR[1]=0x00020782;

//ADC 7877 14 Mhz 16 bit
AT91C_BASE_SPI0->SPI_CSR[2]=0x00020782;;

AT91C_BASE_SPI0->SPI_CR=0x1000001;//enable SPI0
}
unsigned char Flash_Send(unsigned char u,unsigned int last)
{
//last=0x1000000
AT91C_BASE_SPI0->SPI_TDR=((unsigned int)u)|0x000E0000|last;
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
return(AT91C_BASE_SPI0->SPI_RDR&0xFF);
}
Morfko
Спасибо. Так тоже пробовал. Но что-то не хочет работать. В ответ DataFlash отвечает только "FF" и всё. Хотя загрузка программы происходит как раз именно с SPI DataFlash (BMS = 1).
Пробовал задержки всевозможные - один хрен, не помогает. mad.gif
DpInRock
Язык Си замечателен тем, что не бывает двух одинаковых программ.
Это я к чему. Я очень плохо знаю языки программирования, поэтому стараюсь наиболее просто объяснить компилятору чего я хочу.
Morfko
Придется брать осциллограф...
amaora
У Atmel контроллер SPI везде одинаковый да? (это для 9200),
CODE

static int at45_cs;

static void
at45_transfer( void *cmd_ptr,
int cmd_len,
void *dat_ptr,
int dat_len)
{
struct spi_tblk blks[2];
int blk_n = 1;

blks[0].rx = cmd_ptr;
blks[0].tx = cmd_ptr;
blks[0].len = cmd_len;

if (dat_len != 0) {
blks[1].rx = dat_ptr;
blks[1].tx = dat_ptr;
blks[1].len = dat_len;
++blk_n;
}

spi_select(at45_cs);
spi_transfer(blks, blk_n);
}

static int
at45_status()
{
uint8_t req[2];

req[0] = 0xd7;
at45_transfer(req, 2, 0, 0);

return req[1];
}

static void
at45_wait_rdy()
{
while (!(at45_status() & 0x80)) ;
}

int at45_init(int cs)
{
uint8_t req[4];
at45_cs = cs;

spi_mode(at45_cs, SPI_MODE_0, 8, 5, NULL);

req[0] = 0x9f;
at45_transfer(req, 4, 0, 0);

serial_printk(AT45 "Manufacturer ID: %b\n", req[1]);
serial_printk(AT45 "Density Code: %b\n", req[2]);
serial_printk(AT45 "Product Version: %b\n", req[3]);

if (req[1] != 0x1f || req[2] != 0x25) {
serial_printk(AT45 "Unknown Device\n");
return -1;
}

serial_printk(AT45 "Status Register: %b\n", at45_status());

return 0;
}

#define SPI_CPOL_0 (1 << 0)
#define SPI_CPOL_1 0
#define SPI_NCPHA_0 (1 << 1)
#define SPI_NCPHA_1 0

#define SPI_MODE_0 (SPI_CPOL_0 | SPI_NCPHA_1)
#define SPI_MODE_1 (SPI_CPOL_0 | SPI_NCPHA_0)
#define SPI_MODE_2 (SPI_CPOL_1 | SPI_NCPHA_1)
#define SPI_MODE_3 (SPI_CPOL_1 | SPI_NCPHA_0)

struct spi_tblk {
void *rx;
const void *tx;
int len;
};

static int csdec[] = {
0x000e0000,
0x000d0000,
0x000b0000,
0x00070000,
};

void spi_init()
{
uint32_t tmp32;

tmp32 = ( AT91C_PA0_MISO |
AT91C_PA1_MOSI |
AT91C_PA2_SPCK |
AT91C_PA3_NPCS0 |
AT91C_PA4_NPCS1 |
AT91C_PA5_NPCS2 |
AT91C_PA6_NPCS3 );

AT91C_BASE_PIOA->PIO_ASR = tmp32;
AT91C_BASE_PIOA->PIO_PDR = tmp32;

AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);

AT91C_BASE_SPI->SPI_IDR = 0xffffffff;
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
AT91C_BASE_SPI->SPI_MR = (AT91C_SPI_MSTR |
AT91C_SPI_MODFDIS | AT91C_SPI_PCS | (0x1f << 24));
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
}

void spi_mode(int cs, int pol, int bits, int baud, int dely)
{
AT91C_BASE_SPI->SPI_CSR[cs] = (pol | ((bits - 8) << 4) | (baud << 8) |
((dely) << 24) | ((dely >> 1) << 16));
}

void spi_select(int cs)
{
uint32_t tmp32 = AT91C_BASE_SPI->SPI_MR;
AT91C_BASE_SPI->SPI_MR = (tmp32 & ~(0x000f0000)) | csdec[cs];
}

void spi_transfer(struct spi_tblk *blk, int n)
{
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS;

AT91C_BASE_SPI->SPI_TPR = (uint32_t) blk[0].tx;
AT91C_BASE_SPI->SPI_TCR = blk[0].len;
AT91C_BASE_SPI->SPI_RPR = (uint32_t) blk[0].rx;
AT91C_BASE_SPI->SPI_RCR = blk[0].len;

if (n > 1) {
AT91C_BASE_SPI->SPI_TNPR = (uint32_t) blk[1].tx;
AT91C_BASE_SPI->SPI_TNCR = blk[1].len;
AT91C_BASE_SPI->SPI_RNPR = (uint32_t) blk[1].rx;
AT91C_BASE_SPI->SPI_RNCR = blk[1].len;
}

AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;
while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF)) ;

AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS;
}

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.