Encontré un código para Bit Bang en una EEPROM en el MSP430 aquí , pero cambiar los pines a lo que está en mi diseño que no puede leer y escribir. También he agregado un LED para la salida; esto debería parpadear si falla, lo que hace constantemente.
// required
#define SCL BIT6
#define SDA BIT4
#define LED BIT0
#define READ 0xA1
#define WRITE 0xA0
#define FAILURE -1
#define SUCCESS 0
// required
void sendByte(void);
void receiveByte(void);
void sendAck(void);
void receiveAck(void);
void start(void);
void stop(void);
// required
unsigned char txData = 0;
unsigned char rxData = 0;
unsigned char ackFlag = 0;
unsigned char bitCounter = 0;
unsigned int address = 0; // 12 bit address, upper 4 bits should be 0s.
// optional
int writeChar(void);
int readChar(void);
int readCurrentChar(void);
int writeInt(void);
int readInt(void);
// optional
unsigned char charData = 0;
unsigned int intData = 0;
static void __inline__ _delay_cycles(register unsigned int n)
{
__asm__ __volatile__ (
"1: \n"
" dec %[n] \n"
" jne 1b \n"
: [n] "+r"(n));
}
void main(void) {
WDTCTL = WDTPW + WDTHOLD;
P1OUT |= SCL + LED;
P1DIR |= SCL + LED;
address = 2; // set address to 2
charData = 0xEF;
int result = writeChar();
_delay_cycles(100000);
while(1) {
// write char to address 2
int read = readChar();
_delay_cycles(100000);
if(read == FAILURE && result == FAILURE) {
P1OUT ^= LED;
}
_delay_cycles(100000);
}
}
// optional
int readCurrentChar(void) {
start();
txData = READ;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
receiveByte();
ackFlag = 0;
sendAck();
stop();
charData = rxData;
return SUCCESS;
}
// optional
int readChar(void) {
start();
txData = WRITE;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = address >> 8;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = address;
sendByte();
receiveAck();
start();
txData = READ;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
receiveByte();
ackFlag = 0;
sendAck();
charData = rxData;
stop();
return SUCCESS;
}
// optional
int writeChar(void) {
start();
txData = WRITE;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = address >> 8;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = address;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = charData;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
stop();
return SUCCESS;
}
// optional
int readInt(void) {
start();
txData = WRITE;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = address >> 8;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = address;
sendByte();
receiveAck();
start();
txData = READ;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
receiveByte();
ackFlag = 1;
sendAck();
intData = rxData;
intData <<= 8;
receiveByte();
ackFlag = 0;
sendAck();
intData |= rxData;
stop();
return SUCCESS;
}
// optional
int writeInt(void) {
start();
txData = WRITE;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = address >> 8;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = address;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = intData >> 8;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
txData = intData;
sendByte();
receiveAck();
if(!ackFlag)
return FAILURE;
stop();
return SUCCESS;
}
// required
// send byte to slave
void sendByte(void) {
P1DIR |= SDA;
bitCounter = 0;
while(bitCounter < 8) {
(txData & BIT4) ? (P1OUT |= SDA) : (P1OUT &= ~SDA);
P1OUT |= SCL;
txData <<= 1;
bitCounter++;
P1OUT &= ~SCL;
}
P1OUT |= SDA;
P1DIR &= ~SDA;
}
// required
// receive byte from slave
void receiveByte(void) {
bitCounter = 0;
while(bitCounter < 8) {
P1OUT |= SCL;
rxData <<= 1;
bitCounter++;
if(P1IN & SDA) {
rxData |= BIT0;
}
P1OUT &= ~SCL;
}
}
// required
// send master's ACK
void sendAck(void) {
P1DIR |= SDA;
(ackFlag) ? (P1OUT &= ~SDA) : (P1OUT |= SDA);
P1OUT |= SCL;
P1OUT &= ~SCL;
P1OUT |= SDA;
P1DIR &= ~SDA;
}
// required
// receive slave's ACK
void receiveAck(void) {
P1OUT |= SCL;
(P1IN & SDA) ? (ackFlag = 0) : (ackFlag = 1);
P1OUT &= ~SCL;
}
// required
// start condition
void start(void) {
P1OUT |= SCL;
P1DIR |= SDA;
P1OUT &= ~SDA;
P1OUT &= ~SCL;
P1OUT |= SDA;
P1DIR &= ~SDA;
}
// required
// stop condition
void stop(void) {
P1DIR |= SDA;
P1OUT &= ~SDA;
P1OUT |= SCL;
P1OUT |= SDA;
P1DIR &= ~SDA;
}
Estoy utilizando MSP430-GCC como un compilador que no es CCS o IAR. Por eso tengo mi propia función _delay_cycles
. Lo he intentado con CCS y sigue siendo el mismo problema. He adjuntado un Pull up a la SDA.
La hoja de datos de mi EEPROM es aquí . Entonces, ¿cómo voy a tratar de depurar esto?