You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.1 KiB
C
178 lines
4.1 KiB
C
#include <avr/io.h>
|
|
#include <stdint.h>
|
|
#include <avr/interrupt.h>
|
|
|
|
#include "spi.h"
|
|
#include "dataflash.h"
|
|
|
|
// Prevent Double Initialization
|
|
unsigned short dataflash_flag = 0;
|
|
|
|
void dataflash_opcode_and_address(unsigned char opcode, unsigned int page, unsigned int offset)
|
|
{
|
|
SPI_MasterTransfer(opcode);
|
|
SPI_MasterTransfer((unsigned char)(page >> 7) & 0x1f);
|
|
SPI_MasterTransfer(((unsigned char)(offset >> 8) & 0x01) | ((unsigned char)(page) << 1));
|
|
SPI_MasterTransfer((unsigned char)(offset));
|
|
}
|
|
|
|
void dataflash_wait(void)
|
|
{
|
|
DATAFLASH_Chip_Select;
|
|
SPI_MasterTransfer(DATAFLASH_STATUS_REGISTER_READ);
|
|
|
|
while (!(SPI_MasterTransferRead(0x00) & 0x80))
|
|
;
|
|
|
|
DATAFLASH_Chip_Unselect;
|
|
}
|
|
|
|
void dataflash_init(void)
|
|
{
|
|
// Check if already initialized
|
|
if (!(dataflash_flag & 1))
|
|
{
|
|
// Backup Status Register and disable Interrupts
|
|
uint8_t sreg = SREG;
|
|
cli();
|
|
// AT45DB081 doesn't actually need an intialization,
|
|
// only the ChipSelect should be configured as an output.
|
|
DDRB |= (1 << PB4);
|
|
DATAFLASH_Chip_Unselect;
|
|
SPI_MasterInit();
|
|
|
|
// Restore Status Register
|
|
SREG = sreg;
|
|
|
|
// Set dataflash Init Flag
|
|
dataflash_flag = 1;
|
|
}
|
|
}
|
|
|
|
void dataflash_buffer_to_page(unsigned int page, unsigned char buffer)
|
|
{
|
|
dataflash_wait();
|
|
DATAFLASH_Chip_Select;
|
|
|
|
switch (buffer)
|
|
{
|
|
default:
|
|
dataflash_opcode_and_address(DATAFLASH_BUFFER_1_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE,
|
|
page, 0x00);
|
|
break;
|
|
|
|
case 2:
|
|
dataflash_opcode_and_address(DATAFLASH_BUFFER_2_TO_MAIN_MEMORY_PAGE_PROGRAM_WITH_BUILT_IN_ERASE,
|
|
page, 0x00);
|
|
break;
|
|
}
|
|
DATAFLASH_Chip_Unselect;
|
|
}
|
|
|
|
void dataflash_page_to_buffer(unsigned int page, unsigned char buffer)
|
|
{
|
|
dataflash_wait();
|
|
DATAFLASH_Chip_Select;
|
|
|
|
switch (buffer)
|
|
{
|
|
default:
|
|
dataflash_opcode_and_address(DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_1_TRANSFER,
|
|
page, 0x00);
|
|
break;
|
|
|
|
case 2:
|
|
dataflash_opcode_and_address(DATAFLASH_MAIN_MEMORY_PAGE_TO_BUFFER_2_TRANSFER,
|
|
page, 0x00);
|
|
break;
|
|
}
|
|
DATAFLASH_Chip_Unselect;
|
|
}
|
|
|
|
void dataflash_buffer_read(unsigned char buffer, unsigned int offset,
|
|
unsigned int length, unsigned char *array)
|
|
{
|
|
dataflash_wait();
|
|
DATAFLASH_Chip_Select;
|
|
|
|
switch (buffer)
|
|
{
|
|
default:
|
|
dataflash_opcode_and_address(DATAFLASH_BUFFER_1_READ_LF,
|
|
0x00, offset);
|
|
break;
|
|
|
|
case 2:
|
|
dataflash_opcode_and_address(DATAFLASH_BUFFER_2_READ_LF,
|
|
0x00, offset);
|
|
break;
|
|
}
|
|
|
|
offset = 0x00;
|
|
|
|
while (length--)
|
|
{
|
|
array[offset++] = SPI_MasterTransferRead(0x00);
|
|
}
|
|
|
|
DATAFLASH_Chip_Unselect;
|
|
}
|
|
|
|
void dataflash_buffer_write(unsigned char buffer, unsigned int offset,
|
|
unsigned int length, unsigned char *array)
|
|
{
|
|
dataflash_wait();
|
|
DATAFLASH_Chip_Select;
|
|
|
|
switch (buffer)
|
|
{
|
|
default:
|
|
dataflash_opcode_and_address(DATAFLASH_BUFFER_1_WRITE,
|
|
0x00, offset);
|
|
break;
|
|
|
|
case 2:
|
|
dataflash_opcode_and_address(DATAFLASH_BUFFER_2_WRITE,
|
|
0x00, offset);
|
|
break;
|
|
}
|
|
|
|
offset = 0x00;
|
|
|
|
while (length--)
|
|
{
|
|
SPI_MasterTransfer(array[offset++]);
|
|
}
|
|
|
|
DATAFLASH_Chip_Unselect;
|
|
}
|
|
|
|
void dataflash_read(unsigned int page, unsigned int offset,
|
|
unsigned int length, unsigned char *array)
|
|
{
|
|
dataflash_wait();
|
|
DATAFLASH_Chip_Select;
|
|
|
|
dataflash_opcode_and_address(DATAFLASH_CONTINUOUS_ARRAY_READ_LF, page, offset);
|
|
|
|
offset = 0x00;
|
|
|
|
while (length--)
|
|
{
|
|
array[offset++] = SPI_MasterTransferRead(0x00);
|
|
}
|
|
|
|
DATAFLASH_Chip_Unselect;
|
|
}
|
|
|
|
void dataflash_chip_erase(void)
|
|
{
|
|
dataflash_wait();
|
|
DATAFLASH_Chip_Select;
|
|
SPI_MasterTransfer(DATAFLASH_CHIP_ERASE_1);
|
|
SPI_MasterTransfer(DATAFLASH_CHIP_ERASE_2);
|
|
SPI_MasterTransfer(DATAFLASH_CHIP_ERASE_3);
|
|
SPI_MasterTransfer(DATAFLASH_CHIP_ERASE_4);
|
|
DATAFLASH_Chip_Unselect;
|
|
}
|