mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-22 23:56:13 +01:00
Update I2CRailcom.h
Do a TX of 0x09 to check if baudrate is set correctly at end of Init_SC16IS752() Strange thing is that the UART sent the 0x09 twice, the call is only done once Fixed readback when sending a SRESET, see comments Checked if I can read the LSR, not errors Still no data entering the UART as the RXLV register stay at 0
This commit is contained in:
parent
4739bb16ff
commit
6293b0ae1d
100
IO_I2CRailcom.h
100
IO_I2CRailcom.h
|
@ -87,13 +87,16 @@ public:
|
||||||
DIAG(F("I2CRailcom: %s UART%S detected"),
|
DIAG(F("I2CRailcom: %s UART%S detected"),
|
||||||
_I2CAddress.toString(), exists?F(""):F(" NOT"));
|
_I2CAddress.toString(), exists?F(""):F(" NOT"));
|
||||||
if (!exists) return;
|
if (!exists) return;
|
||||||
|
|
||||||
_UART_CH=0;
|
_UART_CH=0;
|
||||||
Init_SC16IS752(); // Initialize UART0
|
Init_SC16IS752(); // Initialize UART0
|
||||||
|
// HK: currently fixed on CH 0
|
||||||
|
/*
|
||||||
if (_nPins>1) {
|
if (_nPins>1) {
|
||||||
_UART_CH=1;
|
_UART_CH=1;
|
||||||
Init_SC16IS752(); // Initialize UART1
|
Init_SC16IS752(); // Initialize UART1
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (_deviceState==DEVSTATE_INITIALISING) _deviceState=DEVSTATE_NORMAL;
|
if (_deviceState==DEVSTATE_INITIALISING) _deviceState=DEVSTATE_NORMAL;
|
||||||
_display();
|
_display();
|
||||||
}
|
}
|
||||||
|
@ -107,11 +110,40 @@ public:
|
||||||
if (!DCCWaveform::isRailcomSampleWindow()) return;
|
if (!DCCWaveform::isRailcomSampleWindow()) return;
|
||||||
|
|
||||||
// flip channels each loop
|
// flip channels each loop
|
||||||
if (_nPins>1) _UART_CH=_UART_CH?0:1;
|
_UART_CH=0; // Fix _UART_CH to 0 for now
|
||||||
|
//if (_nPins>1) _UART_CH=_UART_CH?0:1;
|
||||||
|
|
||||||
// Read incoming raw Railcom data, and process accordingly
|
// Read incoming raw Railcom data, and process accordingly
|
||||||
auto inlength= UART_ReadRegister(REG_RXLV);
|
|
||||||
if (inlength==0) return;
|
// HK: Read Line Status register first, if bit 7 set we have a FIFO error, need to clear the FIFO and ignore any data and wait for the next cycle
|
||||||
|
auto reg_data = UART_ReadRegister(REG_LSR);
|
||||||
|
//DIAG(F("Railcom: LSR: %s/%d, Val: 0x%x"), _I2CAddress.toString(), _UART_CH, reg_data);
|
||||||
|
if (reg_data & 0x80 ){ // Check bit 7 of LSR, if there is a FIFO error
|
||||||
|
DIAG(F("Railcom: LSR: %s/%d, Val: 0x%x"), _I2CAddress.toString(), _UART_CH, reg_data);
|
||||||
|
UART_WriteRegister(REG_FCR, 0x07,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto inlength = UART_ReadRegister(REG_RXLV);
|
||||||
|
DIAG(F("Railcom: %s/%d RX Fifo lvl: %d"),_I2CAddress.toString(), _UART_CH, inlength);
|
||||||
|
if (inlength==0){
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
#ifdef DIAG_I2CRailcom
|
||||||
|
DIAG(F("Railcom: %s/%d RX Fifo: %d"),_I2CAddress.toString(), _UART_CH, inlength);
|
||||||
|
#endif
|
||||||
|
_outbuf[0]=(byte)(REG_RHR << 3 | _UART_CH << 1);
|
||||||
|
I2CManager.read(_I2CAddress, _inbuf, inlength, _outbuf, 1);
|
||||||
|
#ifdef DIAG_I2CRailcom_data
|
||||||
|
DIAG(F("Railcom %s/%d RX FIFO Data"), _I2CAddress.toString(), _UART_CH);
|
||||||
|
for (int i = 0; i < inlength; i++){
|
||||||
|
DIAG(F("[0x%x]: 0x%x"), i, _inbuf[i]);
|
||||||
|
}
|
||||||
|
auto locoid=_channelMonitors[_UART_CH].getChannel1Loco(_inbuf);
|
||||||
|
DIAG(F("Railcom Channel1=%d"), locoid);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DIAG_I2CRailcom
|
#ifdef DIAG_I2CRailcom
|
||||||
DIAG(F("Railcom: %s/%d RX Fifo: %d"),_I2CAddress.toString(), _UART_CH, inlength);
|
DIAG(F("Railcom: %s/%d RX Fifo: %d"),_I2CAddress.toString(), _UART_CH, inlength);
|
||||||
|
@ -148,7 +180,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
void _display() override {
|
void _display() override {
|
||||||
DIAG(F("I2CRailcom Configured on Vpins:%u-%u %S"), _firstVpin, _firstVpin+_nPins-1,
|
DIAG(F("I2CRailcom: Configured on Vpins:%u-%u %S"), _firstVpin, _firstVpin+_nPins-1,
|
||||||
(_deviceState!=DEVSTATE_NORMAL) ? F("OFFLINE") : F(""));
|
(_deviceState!=DEVSTATE_NORMAL) ? F("OFFLINE") : F(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,23 +214,51 @@ private:
|
||||||
static const uint16_t _divisor = (SC16IS752_XTAL_FREQ_RAILCOM / PRESCALER) / (BAUD_RATE * 16);
|
static const uint16_t _divisor = (SC16IS752_XTAL_FREQ_RAILCOM / PRESCALER) / (BAUD_RATE * 16);
|
||||||
|
|
||||||
void Init_SC16IS752(){
|
void Init_SC16IS752(){
|
||||||
|
if (_UART_CH==0) { // HK: Currently fixed on ch 0
|
||||||
if (_UART_CH==0) {
|
|
||||||
// only reset on channel 0}
|
// only reset on channel 0}
|
||||||
UART_WriteRegister(REG_IOCONTROL, 0x08,false); // UART Software reset
|
UART_WriteRegister(REG_IOCONTROL, 0x08,false); // UART Software reset
|
||||||
_deviceState=DEVSTATE_INITIALISING; // ignores error during reset which seems normal.
|
//_deviceState=DEVSTATE_INITIALISING; // ignores error during reset which seems normal. // HK: this line is moved to below
|
||||||
|
auto iocontrol_readback = UART_ReadRegister(REG_IOCONTROL);
|
||||||
|
if (iocontrol_readback == 0x00){
|
||||||
|
_deviceState=DEVSTATE_INITIALISING;
|
||||||
|
DIAG(F("I2CRailcom: %s SRESET readback: 0x%x"),_I2CAddress.toString(), iocontrol_readback);
|
||||||
|
} else {
|
||||||
|
DIAG(F("I2CRailcom: %s SRESET: 0x%x"),_I2CAddress.toString(), iocontrol_readback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// HK:
|
||||||
UART_WriteRegister(REG_FCR, 0x07,false); // Reset FIFO, clear RX & TX FIFO (write only)
|
// You write 0x08 to the IOCONTROL register, setting bit 3 (SRESET), as per datasheet 8.18:
|
||||||
UART_WriteRegister(REG_MCR, 0x00); // Set MCR to all 0, includes Clock divisor
|
// "Software Reset. A write to this bit will reset the device. Once the
|
||||||
UART_WriteRegister(REG_LCR, 0x80); // Divisor latch enabled
|
// device is reset this bit is automatically set to logic 0"
|
||||||
UART_WriteRegister(REG_DLL, _divisor); // Write DLL
|
// So you can not readback the val you have written as this has changed.
|
||||||
UART_WriteRegister(REG_DLH, (uint8_t)(_divisor >> 8)); // Write DLH
|
// I've added an extra UART_ReadRegister(REG_IOCONTROL) and check if the return value is 0x00
|
||||||
UART_WriteRegister(REG_LCR, WORD_LEN | STOP_BIT | PARITY_ENA | PARITY_TYPE); // Divisor latch disabled
|
// then set _deviceState=DEVSTATE_INITIALISING;
|
||||||
UART_WriteRegister(REG_FCR, 0x07,false); // Reset FIFO, clear RX & TX FIFO (write only)
|
|
||||||
|
|
||||||
|
|
||||||
|
// HK: only do clear FIFO at end of Init_SC16IS752
|
||||||
|
//UART_WriteRegister(REG_FCR, 0x07,false); // Reset FIFO, clear RX & TX FIFO (write only)
|
||||||
|
|
||||||
|
UART_WriteRegister(REG_MCR, 0x00); // Set MCR to all 0, includes Clock divisor
|
||||||
|
|
||||||
|
//UART_WriteRegister(REG_LCR, 0x80); // Divisor latch enabled
|
||||||
|
|
||||||
|
UART_WriteRegister(REG_LCR, 0x80 | WORD_LEN | STOP_BIT | PARITY_ENA | PARITY_TYPE); // Divisor latch enabled and comm parameters set
|
||||||
|
UART_WriteRegister(REG_DLL, (uint8_t)_divisor); // Write DLL
|
||||||
|
UART_WriteRegister(REG_DLH, (uint8_t)(_divisor >> 8)); // Write DLH
|
||||||
|
auto lcr_readback = UART_ReadRegister(REG_LCR);
|
||||||
|
lcr_readback = lcr_readback & 0x7F;
|
||||||
|
UART_WriteRegister(REG_LCR, lcr_readback); // Divisor latch disabled
|
||||||
|
|
||||||
|
//UART_WriteRegister(REG_LCR, WORD_LEN | STOP_BIT | PARITY_ENA | PARITY_TYPE); // Divisor latch disabled
|
||||||
|
|
||||||
|
UART_WriteRegister(REG_FCR, 0x07,false); // Reset FIFO, clear RX & TX FIFO (write only)
|
||||||
|
|
||||||
|
// Sent some data to check if UART baudrate is set correctly
|
||||||
|
UART_WriteRegister(REG_THR, 9, false);
|
||||||
|
DIAG(F("I2CRailcom: UART %s/%d Test TX = 0x09"),_I2CAddress.toString(), _UART_CH);
|
||||||
|
|
||||||
if (_deviceState==DEVSTATE_INITIALISING) {
|
if (_deviceState==DEVSTATE_INITIALISING) {
|
||||||
DIAG(F("UART %d init complete"),_UART_CH);
|
DIAG(F("I2CRailcom: UART %d init complete"),_UART_CH);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -211,14 +271,14 @@ private:
|
||||||
_outbuf[1]=val;
|
_outbuf[1]=val;
|
||||||
auto status=I2CManager.write(_I2CAddress, _outbuf, (uint8_t)2);
|
auto status=I2CManager.write(_I2CAddress, _outbuf, (uint8_t)2);
|
||||||
if(status!=I2C_STATUS_OK) {
|
if(status!=I2C_STATUS_OK) {
|
||||||
DIAG(F("I2CRailcom %s/%d write reg=0x%x,data=0x%x,I2Cstate=%d"),
|
DIAG(F("I2CRailcom: %s/%d write reg=0x%x,data=0x%x,I2Cstate=%d"),
|
||||||
_I2CAddress.toString(), _UART_CH, reg, val, status);
|
_I2CAddress.toString(), _UART_CH, reg, val, status);
|
||||||
_deviceState=DEVSTATE_FAILED;
|
_deviceState=DEVSTATE_FAILED;
|
||||||
}
|
}
|
||||||
if (readback) { // Read it back to cross check
|
if (readback) { // Read it back to cross check
|
||||||
auto readback=UART_ReadRegister(reg);
|
auto readback=UART_ReadRegister(reg);
|
||||||
if (readback!=val) {
|
if (readback!=val) {
|
||||||
DIAG(F("I2CRailcom %s/%d reg:0x%x write=0x%x read=0x%x"),_I2CAddress.toString(),_UART_CH,reg,val,readback);
|
DIAG(F("I2CRailcom readback: %s/%d reg:0x%x write=0x%x read=0x%x"),_I2CAddress.toString(),_UART_CH,reg,val,readback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +289,7 @@ private:
|
||||||
_inbuf[0]=0;
|
_inbuf[0]=0;
|
||||||
auto status=I2CManager.read(_I2CAddress, _inbuf, 1, _outbuf, 1);
|
auto status=I2CManager.read(_I2CAddress, _inbuf, 1, _outbuf, 1);
|
||||||
if (status!=I2C_STATUS_OK) {
|
if (status!=I2C_STATUS_OK) {
|
||||||
DIAG(F("I2CRailcom %s/%d read reg=0x%x,I2Cstate=%d"),
|
DIAG(F("I2CRailcom read: %s/%d read reg=0x%x,I2Cstate=%d"),
|
||||||
_I2CAddress.toString(), _UART_CH, reg, status);
|
_I2CAddress.toString(), _UART_CH, reg, status);
|
||||||
_deviceState=DEVSTATE_FAILED;
|
_deviceState=DEVSTATE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user