Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MBED_LIN_RGB_Master_Example
Revision 8:63d341e53cce, committed 2020-06-15
- Comitter:
- bollenn
- Date:
- Mon Jun 15 12:42:04 2020 +0000
- Parent:
- 7:53b2cded83f3
- Commit message:
- Rework receive path
Changed in this revision
| LinMaster.cpp | Show annotated file Show diff for this revision Revisions of this file |
| LinMaster.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/LinMaster.cpp Mon Jun 08 11:59:35 2020 +0000
+++ b/LinMaster.cpp Mon Jun 15 12:42:04 2020 +0000
@@ -27,17 +27,16 @@
const uint8_t breakPeriodMessage = 40; /* number of timer overflows in the break field during normal LIN messages */
const uint8_t breakPeriodAcfg = 74; /* number of timer overflows in the break field during autoconfig messages */
-
-LinMaster::LinMaster(PinName InPin, PinName OutPin) : LinOutPin(OutPin), LinInPin(InPin), LinIntPin(InPin)
+
+LinMaster::LinMaster(PinName InPin, PinName OutPin) : LinOutPin(OutPin), LinInPin(InPin, PullUp)
{
- this->DriverState = INIT;
- this->LastError = NoError;
+ this->DriverState = INIT;
+ this->LastError = NoError;
this->LinOutPin.write(1);
-
- this->LinInPin.mode(PullUp);
-
- this->LinIntPin.disable_irq();
+
+ this->LinInPin.disable_irq();
+ this->LinInPin.fall(NULL);
this->DriverState = IDLE;
@@ -46,65 +45,66 @@
LinMaster::~LinMaster()
{
- this->LinIntPin.disable_irq();
- this->MyTicker.detach();
- this->MyTimer.stop();
+ this->LinInPin.disable_irq();
+ this->LinInPin.fall(NULL);
+ this->HalfbitTicker.detach();
+ this->TimeoutTicker.detach();
}
bool LinMaster::init(void)
{
this->LinOutPin.write(1);
-
- this->LinInPin.mode(PullUp);
- this->LinIntPin.disable_irq();
-
+ this->LinInPin.enable_irq();
+ this->LinInPin.fall(NULL);
+
this->DriverState = IDLE;
-
+
return ( true );
}
bool LinMaster::baudrate(uint16_t uBaud)
{
bool blReturn = false;
-
+
if ((uBaud > 0) && (uBaud <= 20000))
{
- this->u16HalfBitPeriod = 1000000/(2*uBaud);
+ this->u16HalfBitPeriod = std::chrono::microseconds(1000000 / ( 2 * uBaud));
blReturn = true;
}
-
+
return ( blReturn );
}
uint16_t LinMaster::baudrate(void)
{
- return ( 1000000 / (2 * this->u16HalfBitPeriod) );
+ return ( 1000000 / (2 * this->u16HalfBitPeriod.count()) );
}
bool LinMaster::send_frame(Frame_t * ptrFrame)
{
bool blReturn = false;
-
+
if ( (this->DriverState == IDLE) && (this->LinInPin.read() == 1) )
{
/* Clear and initialize all registers */
memset(this->RXbuf, 0, 11);
-
- /* Disable half bit interrupt */
- this->MyTicker.detach();
-
- this->LinIntPin.disable_irq();
-
+
+ /* Disable ticker interrupt */
+ this->HalfbitTicker.detach();
+ this->TimeoutTicker.detach();
+
+ this->LinInPin.fall(NULL);
+
this->LinOutPin.write(1);
-
+
this->DriverState = TRANSMIT; /* State of the LIN bus is transceiving a frame */
this->LastError = NoError;
this->FrameStatus = FStart;
this->ByteStatus = BStart;
this->RXbufIndex = 0; /* Reset index in the receiver buffer */
this->TXbufIndex = 0; /* Reset index in the transmit buffer */
-
+
/* Set the correct brake-length */
if (ptrFrame->Brake == AutoConfig)
{
@@ -114,19 +114,19 @@
{
this->breakLength = breakPeriodMessage;
}
-
+
this->FrameLength = 1 + 1 + ptrFrame->DataLen + 1; /* Frame length = Sync + Frame ID + Data Len + CRC */
this->linMessageType = ptrFrame->FrameType;
-
+
/* Create the correct frame buffer */
this->TXbuf[0] = 0x55; /* Sync field */
this->TXbuf[1] = this->parity(ptrFrame->FrameID); /* Frame ID */
-
+
if (this->linMessageType == M2S)
{
uint16_t u16Crc;
uint8_t i;
-
+
if (ptrFrame->CrcType == Enhanced)
{
u16Crc = TXbuf[1];
@@ -135,7 +135,7 @@
{
u16Crc = 0;
}
-
+
for (i = 0; i < ptrFrame->DataLen; i++)
{
this->TXbuf[i + 2] = ptrFrame->Data[i]; /* Data */
@@ -150,13 +150,14 @@
else
{
/* S2M message */
- this->RXtimeout = ((ptrFrame->DataLen + 1) * 14) * 2; /* Calculate RX timeout in half bit-times */
- this->RXtimeoutSubCTR = 0;
+
+ /* Calculate RX timeout */
+ this->FrameTimeout = std::chrono::microseconds(((ptrFrame->DataLen + 1) * 14) * 2 * this->u16HalfBitPeriod);
}
-
+
/* Configure and start the half bit timer */
- this->MyTicker.attach_us(this, &LinMaster::TickEventHndl, this->u16HalfBitPeriod);
-
+ this->HalfbitTicker.attach(callback(this, &LinMaster::TickEventHndl), this->u16HalfBitPeriod);
+
blReturn = true;
}
@@ -205,6 +206,8 @@
void LinMaster::TickEventHndl(void)
{
+ int PinLevel = this->LinInPin.read();
+
if (this->FrameStatus < Break_OK)
{
/* Do break field transmission */
@@ -235,11 +238,12 @@
{
/* No data needs to be transmitted */
- /* Disable half bit interrupt */
- this->MyTicker.detach();
+ /* Disable ticker interrupt */
+ this->HalfbitTicker.detach();
+ this->TimeoutTicker.detach();
/* Disable LIN bus level interrupt */
- this->LinIntPin.disable_irq();
+ this->LinInPin.fall(NULL);
}
else
{
@@ -253,27 +257,11 @@
this->ByteStatus = static_cast<ByteStatus_t>(static_cast<int>(this->ByteStatus)+1);
}
- if (this->RXtimeout > 0)
- {
- this->RXtimeout--;
- }
- else
- {
- this->DriverState = IDLE;
- this->LastError = NoSlaveResp;
-
- /* Disable half bit interrupt */
- this->MyTicker.detach();
-
- /* Disable LIN bus level interrupt */
- this->LinIntPin.disable_irq();
- }
-
/* S2M message data receiving */
switch (this->ByteStatus)
{
case StartbitSample:
- if (LinInPin.read() == 0)
+ if (PinLevel == 0)
{
/* OK */
}
@@ -294,43 +282,44 @@
case Databit7Sample:
/* Mid of single bit time, do sampling */
this->RXbuf[RXbufIndex] >>= 1;
- this->RXbuf[RXbufIndex] |= (LinInPin.read() << 7);
+ this->RXbuf[RXbufIndex] |= (PinLevel << 7);
break;
case StopbitSample:
/* End of stop bit, stop Timer IRQ */
+
+ /* Enable LIN bus level interrupt */
+ this->LinInPin.fall(callback(this, &LinMaster::PinEventHndl));
+
+ /* Disable half bit interrupt */
+ this->HalfbitTicker.detach();
+
+ /* Check the current bus level */
+ if (PinLevel == 0)
+ {
+ this->LastError = FramingErr; /* stop bit not valid => framing error */
+ }
+
this->RXbufIndex++;
this->FrameStatus = static_cast<FrameStatus_t>(static_cast<int>(this->FrameStatus)+1);
this->ByteStatus = BStart;
- /* Check the current bus level */
- if (this->LinInPin.read() == 0)
- {
- this->LastError = FramingErr; /* stop bit not valid => framing error */
- }
-
if ((this->RXbufIndex >= this->FrameLength) ||
(this->LastError != NoError))
{
/* All requested data bytes are received or an error occurred */
this->DriverState = IDLE;
- /* Disable half bit interrupt */
- this->MyTicker.detach();
-
/* Disable LIN bus level interrupt */
- this->LinIntPin.disable_irq();
+ this->LinInPin.fall(NULL);
+
+ /* Disable timeout ticker */
+ this->TimeoutTicker.detach();
}
else
{
/* Wait for a new data byte */
- this->MyTimer.start();
-
- /* Disable LIN bus level interrupt */
- this->LinIntPin.fall(this, &LinMaster::PinEventHndl);
- this->LinIntPin.enable_irq();
}
-
break;
case Databit0Edge:
@@ -398,7 +387,7 @@
case Databit7Sample:
/* Odd overflow, mid of bit time ==> sample the bus for RX */
this->RXbuf[this->RXbufIndex] >>= 1;
- this->RXbuf[this->RXbufIndex] |= ((LinInPin.read() << 7) & 0x80);
+ this->RXbuf[this->RXbufIndex] |= ((PinLevel << 7) & 0x80);
break;
case StopbitEdge:
@@ -408,54 +397,56 @@
case StopbitSample:
/* Stop bit : mid / level check */
- if (this->LinInPin.read() == 0)
+ if (PinLevel == 0)
{
/* Stop bit not valid => framing error */
this->LastError = FramingErr;
this->DriverState = IDLE;
-
- /* Disable half bit interrupt */
- this->MyTicker.detach();
-
+
+ /* Disable ticker interrupt */
+ this->HalfbitTicker.detach();
+ this->TimeoutTicker.detach();
+
/* Disable LIN bus level interrupt */
- this->LinIntPin.disable_irq();
+ this->LinInPin.fall(NULL);
}
+ this->FrameStatus = static_cast<FrameStatus_t>(static_cast<int>(this->FrameStatus)+1);
+ this->TXbufIndex++;
+ this->RXbufIndex++;
+
+ if ((this->linMessageType == S2M) && (this->FrameStatus == ID_OK))
+ {
+ /* Stop bit of header is sent, now start receiving data bytes */
+
+ /* Enable LIN bus level interrupt */
+ this->LinInPin.fall(callback(this, &LinMaster::PinEventHndl));
+
+ /* Disable half bit interrupt */
+ this->HalfbitTicker.detach();
+
+ /* Enable frame timeout interrupt */
+ this->TimeoutTicker.attach(callback(this, &LinMaster::RXtimeoutEventHndl), this->FrameTimeout);
+ }
break;
case BDone:
/* Stop bit : finished */
this->ByteStatus = BStart;
- this->FrameStatus = static_cast<FrameStatus_t>(static_cast<int>(this->FrameStatus)+1);
- this->TXbufIndex++;
- this->RXbufIndex++;
- if (this->linMessageType == S2M)
- {
- /* S2M frame */
- if (this->FrameStatus == ID_OK)
- {
- /* Stop bit of header is sent, now start receiving data bytes */
- this->MyTimer.start();
-
- /* Enable LIN bus level interrupt */
- this->LinIntPin.fall(this, &LinMaster::PinEventHndl);
- this->LinIntPin.enable_irq();
- }
- }
- else if (this->TXbufIndex >= this->FrameLength)
+ if (this->TXbufIndex >= this->FrameLength)
{
/* M2S frame, Last byte is sent */
this->LastError = NoError;
this->DriverState = IDLE;
-
- /* Disable half bit interrupt */
- this->MyTicker.detach();
-
+
/* Disable LIN bus level interrupt */
- this->LinIntPin.disable_irq();
+ this->LinInPin.fall(NULL);
+
+ /* Disable ticker interrupts */
+ this->TimeoutTicker.detach();
+ this->HalfbitTicker.detach();
}
-
break;
default:
@@ -466,6 +457,19 @@
}
}
+void LinMaster::RXtimeoutEventHndl(void)
+{
+ /* Disable LIN bus level interrupt */
+ this->LinInPin.fall(NULL);
+
+ /* Disable half bit interrupt */
+ this->HalfbitTicker.detach();
+ this->TimeoutTicker.detach();
+
+ this->DriverState = IDLE;
+ this->LastError = NoSlaveResp;
+}
+
void LinMaster::PinEventHndl(void)
{
switch (this->DriverState)
@@ -473,29 +477,16 @@
case TRANSMIT:
case RECEIVE:
{
- this->ByteStatus = StartbitEdge; /* Set status of the received byte */
- this->RXtimeoutSubCTR += this->MyTimer.read_us();
- this->MyTimer.stop();
-
+ this->ByteStatus = StartbitSample; /* Set status of the received byte */
+
/* Reset ticker */
- this->MyTicker.detach();
- this->MyTicker.attach_us(this, &LinMaster::TickEventHndl, this->u16HalfBitPeriod);
-
+ this->HalfbitTicker.attach(callback(this, &LinMaster::TickEventHndl), this->u16HalfBitPeriod);
+
/* Disable LIN bus level interrupt */
- this->LinIntPin.disable_irq();
-
- if (this->RXtimeoutSubCTR > this->u16HalfBitPeriod)
- {
- this->RXtimeoutSubCTR -= this->u16HalfBitPeriod;
- if (this->RXtimeout > 0)
- {
- this->RXtimeout--;
- }
- }
-
+ this->LinInPin.fall(NULL);
break;
}
-
+
case IDLE:
case DOMINANT:
case TXWAKEUP:
--- a/LinMaster.h Mon Jun 08 11:59:35 2020 +0000
+++ b/LinMaster.h Mon Jun 15 12:42:04 2020 +0000
@@ -22,11 +22,11 @@
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
-#include "mbed.h"
#ifndef MBED_LIN_MASTER_H
#define MBED_LIN_MASTER_H
+
+#include "mbed.h"
/** A master device LIN communication library for mbed
*
@@ -88,7 +88,7 @@
* The current configured LIN baudrate
*/
uint16_t baudrate(void);
-
+
/** Bus status */
enum DriverStatus_t {
INIT, /**< initializing */
@@ -128,19 +128,19 @@
S2M,
M2S
};
-
+
/** CRC Type */
enum CrcType_t {
Classic,
Enhanced
};
-
+
/** Brake Type */
enum BrakeType_t {
Normal,
AutoConfig
};
-
+
/** Frame */
struct Frame_t {
FrameType_t FrameType;
@@ -150,7 +150,7 @@
uint8_t FrameID;
uint8_t Data[8];
};
-
+
/** Send a frame on the LIN bus
*
* @param ptrFrame pointer to the frame to transmit
@@ -159,7 +159,7 @@
* false on fail
*/
bool send_frame(Frame_t * ptrFrame);
-
+
/** Receive a frame on the LIN bus
*
* @param ptrFrame pointer to the frame to receive
@@ -168,9 +168,11 @@
* false on fail
*/
bool get_rx_data(Frame_t & ptrFrame);
-
+
void TickEventHndl(void);
-
+
+ void RXtimeoutEventHndl(void);
+
void PinEventHndl(void);
private:
@@ -189,7 +191,7 @@
Data7,
CRC
};
-
+
enum ByteStatus_t {
BStart,
StartbitEdge, /* Begin of startbit received */
@@ -223,21 +225,19 @@
uint8_t breakLength;
uint8_t FrameLength;
-
+
uint8_t TXbuf[11];
uint8_t TXbufIndex;
uint8_t RXbuf[11];
uint8_t RXbufIndex;
- uint8_t RXtimeout;
- uint16_t RXtimeoutSubCTR;
- uint16_t u16HalfBitPeriod;
+ std::chrono::microseconds u16HalfBitPeriod;
- DigitalOut LinOutPin;
- DigitalIn LinInPin;
- InterruptIn LinIntPin;
- Ticker MyTicker;
- Timer MyTimer;
-
+ DigitalOut LinOutPin;
+ InterruptIn LinInPin;
+ std::chrono::microseconds FrameTimeout;
+ Ticker HalfbitTicker;
+ Ticker TimeoutTicker;
+
uint8_t parity(uint8_t u8BYTE);
};