-
-
Save anonymous/3e085bd2d639f137d1a3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The AT93C46D eeprom can used by an arduino using SPI with modified settings. | |
* In this code I assume that pin 6 (ORG) is connected to GND so the 128x8 organization is selected. | |
* Slave Select needs to be pulled high when using the eeprom where in SPI you normaly pull low to select a chip. | |
* | |
* Before doing an action (reading/writing/..) you need to send a start bit (1), afterwards the opcode for | |
* the action you want to perform (2 bits) and then any other required data. This information can be found in the | |
* datasheet (http://www.atmel.com/images/atmel-5193-seeprom-at93c46d-datasheet.pdf) on page 6. | |
* | |
* As an example when reading a byte you first send a start bit (1) and the opcode (10) followed by the | |
* address (7 bits) afterwards you can retrieve the data (which is always preceded by a 0). | |
* | |
*/ | |
#include<SPI.h> | |
#define DATAOUT 11//MOSI | |
#define DATAIN 12//MISO | |
#define SPICLOCK 13//sck | |
#define SS 10//ss | |
void setup() | |
{ | |
pinMode(SS,OUTPUT); | |
pinMode(DATAOUT, OUTPUT); | |
pinMode(DATAIN, INPUT); | |
pinMode(SPICLOCK,OUTPUT); | |
digitalWrite(SS,LOW); | |
Serial.begin(9600); | |
SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0)); | |
fill(); | |
dump(); | |
} | |
void loop() | |
{ | |
} | |
void fill() | |
{ | |
Serial.println("Filling AT93C46D"); | |
Serial.println("Send EWEN opcode"); | |
digitalWrite(SS,HIGH); | |
SPI.transfer(0b1001); | |
SPI.transfer(0b10000000); | |
digitalWrite(SS,LOW); | |
delay(100); | |
for (int address = 0; address < 128; address++) { | |
digitalWrite(SS,HIGH); | |
SPI.transfer(B10); // 1 start bit, first bit of opcode | |
SPI.transfer(0b10000000 | address); // bitwise or to preced the address by 1 (second opcode bit) | |
SPI.transfer(0b10101010); // the data that is written | |
delay(10); //give the eeprom some time to complete the write request | |
digitalWrite(SS,LOW); | |
} | |
Serial.println("Done filling eeprom"); | |
delay(100); | |
Serial.println("Send EWDS opcode"); | |
digitalWrite(SS,HIGH); | |
SPI.transfer(0b1000); | |
SPI.transfer(0b00000000); | |
digitalWrite(SS,LOW); | |
delay(10); | |
} | |
void dump(){ | |
Serial.println("Dumping AT93C46D"); | |
byte data1; | |
byte data2; | |
for (int address = 0; address < 128; address++) { | |
digitalWrite(SS,HIGH); | |
SPI.transfer(0b11); // start bit and first bit of read opcode | |
SPI.transfer(address); // second bit of read opcode is 0 so the address is automatically preceded by 0 | |
data1 = SPI.transfer(0); // data1 contains a 0 and the first 7 bits at the address | |
data2 = SPI.transfer(0); // contains the 8th bit (LSB) | |
digitalWrite(SS,LOW); | |
data1 = data1 << 1; // bitwise shift to get rid of the preceding 0 | |
if (bitRead(data2, 7) == 1){ | |
bitWrite(data1, 0, 1); // change LSB if needed | |
} | |
printByte(data1); | |
} | |
} | |
void printByte(byte data){ // print with all preceding 0's | |
for (int i = 7; i >= 0 ; i--) { | |
if (bitRead(data, i) == 1) { | |
Serial.print(1); | |
} else { | |
Serial.print(0); | |
} | |
} | |
Serial.print("\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is my code for AT93C46D 8 bit. Just completed the testing, maybe will be useful for someone :) :
`/*****************************************************
Eeprom Settings
*****************************************************/
include "hw_config.h"
include "SPI.h"
ifndef EEPROM_AT93C46D_H
define EEPROM_AT93C46D_H
/** Example:
#include "EEPROM_AT93C46D.h"
define spi3_set_cs_1 GPIOA->BSRR = GPIO_BSRR_BS15; //set on PA15 1
define spi3_set_cs_0 GPIOA->BSRR = GPIO_BSRR_BR15; //set on PA15 0
define MISO_spi3 (GPIOB->IDR & 0x0010) //PB4(MISO)
void spi3_init_master(void)
{
//to enable SPI3 nead to disable JTAG!
//AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG;
//AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_DISABLE; //JTAG-DP Disabled and SW-DP Disabled
RCC->APB2ENR |= (RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN); // GPIOA Clock ON. Alter function clock ON
RCC->APB2ENR |= (RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPBEN); // GPIOB Clock ON. Alter function clock ON
GPIOB->CRL &= ~(GPIO_CRL_CNF3 | GPIO_CRL_CNF4 | GPIO_CRL_CNF5); // Clear CNF bit 3, 4 and 5
GPIOA->CRH &= ~(GPIO_CRH_CNF15); // Clear CNF bit 15
GPIOB->CRL |= GPIO_CRL_CNF5_1 | GPIO_CRL_CNF3_1; //PB5(MOSI), PB3(SCK) - AF, Output, PP
GPIOA->CRH &= ~GPIO_CRH_CNF15; //PA15(NSS) - Output, PP
GPIOB->CRL |= GPIO_CRL_MODE5 | GPIO_CRL_MODE3; //Outputs MOSI, SCK - 50MHz
GPIOA->CRH |= GPIO_CRH_MODE15; //Outputs NSS - 50MHz
GPIOB->CRL |= GPIO_CRL_CNF4_0; //PB4(MISO) - Input floating
GPIOB->CRL &= ~GPIO_CRL_MODE4; //PB4(MISO) - Input
//Init SPI3 (Master)
//8 data bits, MSB send first, spi MODE 0, program mode driwe NSS pin NSS (PA4) is alowed to use as output
RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; //SPI3 Clock ON
SPI3->CR1 &= ~SPI_CR1_BR;
SPI3->CR1 |= SPI_CR1_BR_2; //Baud rate = Fpclk(36MHz)/32 (1,125MHz) from max 1.46MHz for AT93C46D and +3.3V
SPI3->CR1 &= ~SPI_CR1_CPOL; //polarity of SCK
SPI3->CR1 &= ~SPI_CR1_CPHA; //phase of SCK
SPI3->CR1 &= ~SPI_CR1_DFF; //8 data bits
SPI3->CR1 &= ~SPI_CR1_LSBFIRST; //MSB send first
SPI3->CR1 |= SPI_CR1_SSM; //program mode driwe NSS
SPI3->CR1 |= SPI_CR1_SSI; //analog as an pin NSS is high level
SPI3->CR2 |= SPI_CR2_SSOE; //pin NSS - pin driwe slave select
SPI3->CR1 |= SPI_CR1_MSTR; //is Master
SPI3->CR1 |= SPI_CR1_SPE; //enable SPI3
}
Delay(10); //3,92s
spi3_init_master();
Delay(10); //3,92s
}
}
*/
void Delay( uint32_t Val);
void spi3_Send_to_eeprom(uint8_t send_data);
void EWEN_instruction(void);
void EWDS_instruction(void);
void WRITE_eeprom(unsigned char ADDR, unsigned char BUTE);
unsigned char Read_eeprom(unsigned char ADDR);
void Erase_eeprom(unsigned char ADDR);
void Delay( uint32_t Val) /* Time to wait in micro seconds. */ //0,098us
{
for( ; Val != 0; Val--)
{
__nop();
};
}
//Send cmd to eeprom
void spi3_Send_to_eeprom(uint8_t send_data)
{
SPI3->DR = send_data; //Pyshemo v bufer peredavacha SPI3
//while(!(SPI3->SR & SPI_SR_TXE)); //Ochikuyemo zavershennya pereda4i danykh modulem SPI3 (TXE =1 - bufer pereda4i porogniy)
while((SPI3->SR & SPI_SR_BSY)||(!(SPI3->SR & SPI_SR_TXE)));
}
//Enable write/erase mode of eeprom
void EWEN_instruction(void)
{
spi3_set_cs_1;
Delay(10); //0,00000098s //0,98uS //tcss = 250ns or more
spi3_Send_to_eeprom(0x09); //00001001
spi3_Send_to_eeprom(0x80); //1xxxxxxx
Delay(10); //0,00000098s //0,98uS //tcsh = 0 or more
spi3_set_cs_0;
}
//Disable write/erase mode of eeprom
void EWDS_instruction(void)
{
spi3_set_cs_1;
Delay(10); //0,00000098s //0,98uS //tcss = 250ns or more
spi3_Send_to_eeprom(0x08); //00001000
spi3_Send_to_eeprom(0x00); //0xxxxxxx
Delay(10); //0,00000098s //0,98uS //tcsh = 0 or more
spi3_set_cs_0;
}
//Read datas from eeprom
unsigned char Read_eeprom(unsigned char ADDR)
{
unsigned char read_eeprom;
spi3_set_cs_1;
Delay(10); //0,00000098s //0,98uS //tcss = 250ns or more
spi3_Send_to_eeprom(0x06); //00000110
spi3_Send_to_eeprom(((ADDR<<1)&(0xfe))); //ADDR + 0 (dumm bit)
read_eeprom = SPI3->DR; //nead to read dummy bute!, dont work without that!
spi3_Send_to_eeprom(0x00); //00000000 // send just clk to receive datas
//while((SPI3->SR & SPI_SR_BSY)||(!(SPI3->SR & SPI_SR_RXNE)));
read_eeprom = SPI3->DR; //read bute
Delay(10); //0,00000098s //0,98uS //tcsh = 0 or more
spi3_set_cs_0;
Delay(10); //0,00000098s //0,98uS //tcs = 250ns...1000ns or more
}
//Write datas to eeprom
void WRITE_eeprom(unsigned char ADDR, unsigned char BUTE)
{
Erase_eeprom(ADDR); //Erase eeprom
}
//Erase eeprom
void Erase_eeprom(unsigned char ADDR)
{
spi3_set_cs_1;
Delay(10); //0,00000098s //0,98uS //tcss = 250ns or more
spi3_Send_to_eeprom(0x03); //00000011
spi3_Send_to_eeprom((ADDR|0x80)); //1 (opcode) + ADDR
Delay(10); //0,00000098s //0,98uS //tcsh = 0 or more
spi3_set_cs_0;
/** wait busy flag clear */
Delay(10); //0,00000098s //0,98uS //250ns < tcs < 1000ns
spi3_set_cs_1;
Delay(10); //0,00000098s //0,98uS //tsv < 250ns...1000ns
while(!MISO_spi3); //wait until end of write //0.1ms < twp < 5ms
}
endif /* EEPROM_AT93C46D_H */
`