kopia lustrzana https://github.com/Schildkroet/GRBL-Advanced
187 wiersze
4.5 KiB
C
187 wiersze
4.5 KiB
C
![]() |
#include "M24C0X.h"
|
||
|
#include "I2C.h"
|
||
|
#include "System32.h"
|
||
|
#include "stm32f4xx_i2c.h"
|
||
|
#include "stm32f4xx_gpio.h"
|
||
|
#include "stm32f4xx_it.h"
|
||
|
|
||
|
|
||
|
#define I2C_SPEED 200000
|
||
|
|
||
|
|
||
|
// Define slave address
|
||
|
#ifndef M24C0X_ADDRESS
|
||
|
#define M24C0X_ADDRESS 0xA0
|
||
|
#endif
|
||
|
|
||
|
// Define I2C peripheral
|
||
|
#ifndef M24C0X_I2C
|
||
|
#define M24C0X_I2C I2C_1
|
||
|
#endif
|
||
|
|
||
|
#define M24C0X_PAGE_SIZE 16
|
||
|
|
||
|
#define WP_DISABLE 0
|
||
|
#define WP_ENABLE 1
|
||
|
|
||
|
|
||
|
|
||
|
static inline void M24C0X_WriteProtection(uint8_t enable);
|
||
|
|
||
|
|
||
|
|
||
|
void M24C0X_Init(void)
|
||
|
{
|
||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||
|
|
||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
||
|
|
||
|
// Initialize write protection pin
|
||
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
|
||
![]() |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||
|
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||
![]() |
|
||
|
// Enable write protection
|
||
![]() |
GPIO_SetBits(GPIOB, GPIO_Pin_12);
|
||
![]() |
|
||
|
I2C_Mode_t mode = {I2C_SPEED, I2C_Mode_I2C, I2C_Ack_Enable};
|
||
|
I2C_Initialize(M24C0X_I2C, &mode);
|
||
|
}
|
||
|
|
||
|
|
||
|
uint8_t M24C0X_ReadByte(uint16_t addr)
|
||
|
{
|
||
|
uint8_t slave_adr = M24C0X_ADDRESS;
|
||
|
|
||
|
if(addr > UINT8_MAX)
|
||
|
{
|
||
|
// If address is bigger than 255 (8 Bit), upper address bits (A8, A9, A10) are coded into slave address (up to 2KB, bigger EEPROMs use 2 Bytes for addressing)
|
||
![]() |
slave_adr |= 0x0E & (addr>>7);
|
||
![]() |
}
|
||
|
|
||
|
return I2C_ReadByte(M24C0X_I2C, slave_adr, addr);
|
||
|
}
|
||
|
|
||
|
|
||
|
uint8_t M24C0X_WriteByte(uint16_t addr, uint8_t data)
|
||
|
{
|
||
|
uint8_t slave_adr = M24C0X_ADDRESS;
|
||
|
|
||
|
if(addr > UINT8_MAX)
|
||
|
{
|
||
|
// If address is bigger than 255 (8 Bit), upper address bits (A8, A9, A10) are coded into slave address (up to 2KB, bigger EEPROMs use 2 Bytes for addressing)
|
||
![]() |
slave_adr |= 0x0E & (addr>>7);
|
||
![]() |
}
|
||
|
|
||
|
M24C0X_WriteProtection(WP_DISABLE);
|
||
|
uint8_t ret = I2C_WriteByte(M24C0X_I2C, slave_adr, addr, data);
|
||
|
M24C0X_WriteProtection(WP_ENABLE);
|
||
|
|
||
|
Delay_ms(5);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
uint8_t M24C0X_ReadByteArray(uint16_t addr, uint8_t *pData, uint16_t len)
|
||
|
{
|
||
|
uint8_t slave_adr = M24C0X_ADDRESS;
|
||
|
|
||
|
if(addr > UINT8_MAX)
|
||
|
{
|
||
|
// If address is bigger than 255 (8 Bit), upper address bits (A8, A9, A10) are coded into slave address (up to 2KB, bigger EEPROMs use 2 Bytes for addressing)
|
||
![]() |
slave_adr |= 0x0E & (addr>>7);
|
||
![]() |
}
|
||
|
|
||
|
I2C_ReadByteArray(M24C0X_I2C, slave_adr, addr, pData, len);
|
||
![]() |
|
||
![]() |
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
uint8_t M24C0X_WriteByteArray(uint16_t addr, uint8_t *pData, uint16_t len)
|
||
|
{
|
||
|
uint8_t ret = 0;
|
||
![]() |
uint16_t bytes2write = len;
|
||
![]() |
uint16_t remainingBytes = len;
|
||
|
uint16_t bytesWritten = 0;
|
||
|
uint8_t timeout = 0;
|
||
|
|
||
|
uint8_t slave_adr = M24C0X_ADDRESS;
|
||
|
|
||
|
|
||
|
// Disable write protection
|
||
|
M24C0X_WriteProtection(WP_DISABLE);
|
||
|
|
||
|
while(remainingBytes)
|
||
|
{
|
||
|
bytes2write = remainingBytes;
|
||
|
|
||
|
if(addr > UINT8_MAX)
|
||
|
{
|
||
|
// If address is bigger than 255 (8 Bit), upper address bits (A8, A9, A10) are coded into slave address (up to 2KB, bigger EEPROMs use 2 Bytes for addressing)
|
||
![]() |
slave_adr |= 0x0E & (addr>>7);
|
||
![]() |
}
|
||
|
|
||
|
// We can write max M24C0X_PAGE_SIZE bytes per write
|
||
|
if(bytes2write > M24C0X_PAGE_SIZE)
|
||
|
{
|
||
|
bytes2write = M24C0X_PAGE_SIZE;
|
||
|
}
|
||
|
|
||
|
// Check if page write is aligned
|
||
|
if(((addr % M24C0X_PAGE_SIZE) + bytes2write) > M24C0X_PAGE_SIZE)
|
||
|
{
|
||
|
bytes2write = M24C0X_PAGE_SIZE - (addr % M24C0X_PAGE_SIZE);
|
||
|
}
|
||
|
|
||
|
// If eeprom is busy (write takes up to 5ms), try again until success or timeout
|
||
|
while((ret = I2C_WriteByteArray(M24C0X_I2C, slave_adr, addr, &pData[bytesWritten], bytes2write)) && (timeout < 4))
|
||
|
{
|
||
|
Delay_ms(2);
|
||
|
timeout++;
|
||
|
}
|
||
|
|
||
|
if(timeout >= 4)
|
||
|
{
|
||
|
// Failed to write
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// Reset timeout
|
||
|
timeout = 0;
|
||
|
|
||
|
remainingBytes -= bytes2write;
|
||
|
bytesWritten += bytes2write;
|
||
|
addr += bytes2write;
|
||
|
|
||
|
Delay_ms(5);
|
||
|
}
|
||
|
|
||
|
// Enable write protection
|
||
|
M24C0X_WriteProtection(WP_ENABLE);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void M24C0X_WriteProtection(uint8_t enable)
|
||
|
{
|
||
![]() |
__ASM("nop");
|
||
![]() |
|
||
|
if(enable)
|
||
|
{
|
||
![]() |
for(volatile uint8_t i = 0; i < 110; i++) __ASM("nop");
|
||
![]() |
GPIO_SetBits(GPIOB, GPIO_Pin_12);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
![]() |
for(volatile uint8_t i = 0; i < 20; i++) __ASM("nop");
|
||
![]() |
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
|
||
|
}
|
||
|
__ASM("nop");
|
||
|
}
|