소스 검색

Wire first working on IMXRT

main
PaulStoffregen 6 년 전
부모
커밋
bdbdb91154
2개의 변경된 파일40개의 추가작업 그리고 20개의 파일을 삭제
  1. +39
    -19
      WireIMXRT.cpp
  2. +1
    -1
      WireIMXRT.h

+ 39
- 19
WireIMXRT.cpp 파일 보기

@@ -81,25 +81,28 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
// wait while bus is busy
while (1) {
status = LPI2C1_MSR; // pg 2899 & 2892
if (!(LPI2C1_MSR & LPI2C_MSR_BBF)) break; // bus is available
if (LPI2C1_MSR & LPI2C_MSR_MBF) break; // we already have bus control
if (!(status & LPI2C_MSR_BBF)) break; // bus is available
if (status & LPI2C_MSR_MBF) break; // we already have bus control
// TODO: timeout...
}
printf("idle\n");
//printf("m=%x\n", status);

// TODO: is this correct if the prior use didn't send stop?
LPI2C1_MSR = LPI2C_MSR_PLTF | LPI2C_MSR_ALF | LPI2C_MSR_NDF | LPI2C_MSR_SDF; // clear flags
//LPI2C1_MSR = LPI2C_MSR_PLTF | LPI2C_MSR_ALF | LPI2C_MSR_NDF | LPI2C_MSR_SDF; // clear flags
LPI2C1_MSR = status;

printf("MSR=%lX, MFSR=%lX\n", status, LPI2C1_MFSR);
//printf("MSR=%lX, MFSR=%lX\n", status, LPI2C1_MFSR);
//elapsedMillis timeout=0;

while (1) {
// transmit stuff, if we haven't already
if (i <= len) {
uint32_t fifo_used = LPI2C1_MFSR & 0x07; // pg 2914
if (fifo_used < 4) printf("t=%ld\n", fifo_used);
//if (fifo_used < 4) printf("t=%ld\n", fifo_used);
while (fifo_used < 4) {
if (i == 0) {
LPI2C1_MTDR = LPI2C_MTDR_CMD_START | (txBuffer[0] << 1);
//printf("start %x\n", txBuffer[0]);
LPI2C1_MTDR = LPI2C_MTDR_CMD_START | txBuffer[0];
i = 1;
} else if (i < len) {
LPI2C1_MTDR = LPI2C_MTDR_CMD_TRANSMIT | txBuffer[i++];
@@ -114,13 +117,13 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
// monitor status
status = LPI2C1_MSR; // pg 2899 & 2892
if (status & LPI2C_MSR_ALF) {
printf("arbitration lost\n");
//printf("arbitration lost\n");
return 4; // we lost bus arbitration to another master
}
if (status & LPI2C_MSR_NDF) {
printf("got NACK, fifo=%ld, i=%ld\n", LPI2C1_MFSR & 0x07, i);
//printf("NACK, f=%d, i=%d\n", LPI2C1_MFSR & 0x07, i);
// TODO: check that hardware really sends stop automatically
// TODO: do we need to clear the FIFO here?
LPI2C1_MCR = LPI2C_MCR_MEN | LPI2C_MCR_RTF; // clear the FIFO
return 2; // NACK for address
//return 3; // NACK for data TODO: how to discern addr from data?
}
@@ -128,16 +131,26 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
//printf("bus stuck - what to do?\n");
//return 4;
//}

//if (timeout > 100) {
//printf("status = %x\n", status);
//timeout = 0;
//}

if (sendStop) {
if (status & LPI2C_MSR_SDF) return 0;
if (status & LPI2C_MSR_SDF) {
//printf("stop sent, msr=%x\n", status);
return 0;
}
} else {
uint32_t fifo_used = LPI2C1_MFSR & 0x07; // pg 2914
if (fifo_used == 0) {
//digitalWriteFast(15, HIGH);
//delayMicroseconds(2);
//digitalWriteFast(15, LOW);
// TODO: this return before the data transmits!
// TODO: this returns before the last data transmits!
// Should verify every byte ACKs, arbitration not lost
//printf("fifo empty, msr=%x\n", status);
return 0;
}
}
@@ -147,16 +160,15 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t length, uint8_t sendStop)
{
uint32_t cmd=0, status, fifo;
// TODO: sendStop is currently ignored

// wait while bus is busy
while (1) {
status = LPI2C1_MSR; // pg 2899 & 2892
if (!(LPI2C1_MSR & LPI2C_MSR_BBF)) break; // bus is available
if (LPI2C1_MSR & LPI2C_MSR_MBF) break; // we already have bus control
if (!(status & LPI2C_MSR_BBF)) break; // bus is available
if (status & LPI2C_MSR_MBF) break; // we already have bus control
// TODO: timeout...
}
printf("idle\n");
//printf("idle2, msr=%x\n", status);

// TODO: is this correct if the prior use didn't send stop?
LPI2C1_MSR = LPI2C_MSR_PLTF | LPI2C_MSR_ALF | LPI2C_MSR_NDF | LPI2C_MSR_SDF; // clear flags
@@ -168,11 +180,13 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t length, uint8_t sendStop)
rxBufferIndex = 0;
rxBufferLength = 0;

//elapsedMillis timeout=0;

while (1) {
// transmit stuff, if we haven't already
if (cmd < 3) {
fifo = LPI2C1_MFSR & 0x07; // pg 2914
if (fifo < 4) printf("t=%ld\n", fifo);
//if (fifo < 4) printf("t=%ld\n", fifo);
while (fifo < 4 && cmd < 3) {
if (cmd == 0) {
LPI2C1_MTDR = LPI2C_MTDR_CMD_START | 1 | address;
@@ -199,14 +213,20 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t length, uint8_t sendStop)
// monitor status
status = LPI2C1_MSR; // pg 2899 & 2892
if (status & LPI2C_MSR_ALF) {
printf("arbitration lost\n");
//printf("arbitration lost\n");
break;
}
if (status & LPI2C_MSR_NDF) {
printf("got NACK\n");
//printf("got NACK\n");
// TODO: how to make sure stop is sent?
break;
}

//if (timeout > 250) {
//printf("Status = %x\n", status);
//timeout = 0;
//}

if (rxBufferLength >= length && cmd >= 3) break;
}
//digitalWriteFast(15, HIGH);

+ 1
- 1
WireIMXRT.h 파일 보기

@@ -33,7 +33,7 @@
#include <stdint.h>

#define BUFFER_LENGTH 32
#define WIRE_HAS_END 1
//#define WIRE_HAS_END 1

class TwoWire : public Stream
{

Loading…
취소
저장