EDIT: For those who tried to help or have found this question via google, I managed to solve this issue just by adding a 1uF ceramic bypass capacitor to the breadboard. Thanks for the answers.
I'm trying to program a AT28C64B with an STM32(running at 168MHz in case it's relevant). I have done something similar using 32K parallel SRAM chips so I assumed I could use some existing code by taking the EEPROM's required delays into account.However I can't write anything to the chip and I consistently read the same wrong values. Here's the code, I know it's a little messy but I'll tidy it up once it works.
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART3_UART_Init();
MX_USB_OTG_FS_PCD_Init();
/* Initialize interrupts */
MX_NVIC_Init();
/* USER CODE BEGIN 2 */
int delayconst = 500;
//int limit =sizeof(values)/sizeof(uint8_t);
int limit = 15;
setvbuf(stdin, NULL, _IONBF, 0);//disable buffers on stdin and stdout
setvbuf(stdout, NULL, _IONBF, 0);
__HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);//enable receive interrupt
//
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
/*
* 28C64B programmer, 8192 addresses 0-8191
* PB[0-7] -> IO[1-8]
* PB[8-15] -> A[0-7]
* PE[2-6] -> A[8-12]
* PC8 -> WE high by default
* PC9 -> OE
* PC10 -> CE high by default
*
*/
while (1)
{
uint8_t data;
int but = 0;
int errors = 0;
printf("Press user button to program EEPROM\n");
while(but == 0){
but = HAL_GPIO_ReadPin(USER_Btn_GPIO_Port, USER_Btn_Pin);
}
but = 0;
printf("Programming EEPROM\n");
GPIOB->MODER = (GPIOB->MODER & ~0xFFFF) | 0b0101010101010101; //make PB0-7 outputs
HAL_GPIO_WritePin(GPIOC, OE_Pin, GPIO_PIN_SET);//disable OE before writing data
for(uint8_t address = 0; address < limit; ++address){
HAL_GPIO_WritePin(GPIOC, WE_Pin, GPIO_PIN_SET);//disable WE before wiritng addresses+data
GPIOB->ODR = (GPIOB->ODR & ~(0xFFFF)) | ((address & 0xFF)<<8) | values[address]; //first 8 address bits to PB8-15, data to pb-7
GPIOE->ODR = (GPIOE->ODR & ~(0b11111<<2)) | ((address &0x1F00)>>6);//upper 5 address bytes to pe2-6
for (volatile int i=0; i!=delayconst; i++);//"1us" delay
HAL_GPIO_WritePin(GPIOC, CE_Pin, GPIO_PIN_RESET);//enable CE after address and data are set
HAL_GPIO_WritePin(GPIOC, WE_Pin, GPIO_PIN_RESET);
for (volatile int i=0; i!=delayconst; i++);//"1us" delay
HAL_GPIO_WritePin(GPIOC, WE_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, CE_Pin, GPIO_PIN_SET);
HAL_Delay(10);//10ms write cycle
}
printf("EEPROM programmed, verify?\n\r");//
while(but == 0){
but = HAL_GPIO_ReadPin(USER_Btn_GPIO_Port, USER_Btn_Pin);
}
but = 0;
GPIOB->MODER &= ~0xFFFF; //make PB0-7 inputs by setting first 16 bits of MODER to 0
HAL_GPIO_WritePin(GPIOC, OE_Pin, GPIO_PIN_RESET);//chip in standby but prepared for read mode
HAL_GPIO_WritePin(GPIOC, WE_Pin, GPIO_PIN_SET);
for(int address = 0; address < limit; ++address){
GPIOB->ODR = (GPIOB->ODR & ~(0xFF<<8)) | ((address & 0xFF)<<8); //first 8 address bits to PB8-15
GPIOE->ODR = (GPIOE->ODR & ~(0b11111<<2)) | ((address &0x1F00)>>6);//upper 5 address bytes to pe2-6
for (volatile int i=0; i!=delayconst; i++);//"1us" delay
HAL_GPIO_WritePin(GPIOC, CE_Pin, GPIO_PIN_RESET);//activate chip and read data
for (volatile int i=0; i!=delayconst; i++);//"1us" delay
data = (GPIOB->IDR & 0xFF);
if(data != values[address]){
++errors;
printf("Found error at %X. Expected %X, got %X\n\r", address, values[address], data);
}
HAL_GPIO_WritePin(GPIOC, CE_Pin, GPIO_PIN_SET);
for (volatile int i=0; i!=delayconst; i++);//"1us" delay
}
printf("Found %i errors. Waiting for button.", errors);
while(but == 0){
but = HAL_GPIO_ReadPin(USER_Btn_GPIO_Port, USER_Btn_Pin);
}
but = 0;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}
To clarify things, PB0-7 are connected to IO0-7, PB8-15 are connected to A0-7, PE2-6 are connected to A8-12 and PC8,PC9 and PC10 are connected to WE, OE and CE respectively. The chip is supplied with 5V and directly connected to 5V-tolerant GPIO pins. I'm sure the parts with the GPIO registers are not the problem because I used them with SRAM chips connected similarly and had no problems.
The first for loop(which writes data to the chip) looks ugly because I tried to replicate the write waveforms in the datasheet but it didn't help. I used a for loop with a volatile-declared index to create delays in the range of microseconds and experimented with many values of delayconst between 500 and 500000 to change the delay's duration but I always read the same wrong values every time. I'm starting to think the write protection feature is active somehow. Does anyone have an idea what the problem might be?