finally fixed the last known bit of i2c corruption

needed to implement clock stretching on start/stop routines too.

program tick timer on sub MCU doesn't really need to be highest priority so made i2c higher priority.
This commit is contained in:
true 2024-10-26 00:13:53 -07:00
parent 0a940b692d
commit ee4a12c9c5
3 changed files with 9 additions and 9 deletions

View File

@ -20,6 +20,9 @@
* CYCLES_TO_HI = 2, CYCLES_TO_LOW = 0: ~650KHz
* CYCLES_TO_HI = 1, bit_delay_lo = __nop: ~900KHz, but sub MCU fails to respond
*
* speed settings chosen are what the lowest speed device (the sub MCU) will
* handle without faults.
*
*/
#include <CH59x_common.h>
@ -27,7 +30,7 @@
#define CYCLES_TO_HI 3
#define CYCLES_TO_HI 2
#define CYCLES_TO_LO 0
//#define CYCLES_RD 2 // cycles spent in read routine
@ -101,6 +104,7 @@ void i2cm_start()
{
SDA_IN_HI(); bit_delay_hi();
SCL_IN_HI(); bit_delay_hi();
while (!SCL_GET()); // clock stretch
SDA_OUTLO(); bit_delay_lo();
SCL_OUTLO(); bit_delay_lo();
}
@ -111,8 +115,7 @@ void i2cm_restart()
SDA_IN_HI(); bit_delay_hi();
SCL_IN_HI();
while (!SCL_GET()); // clock stretch
bit_delay_hi(); // wait a little bit
bit_delay_hi(); // sub MCU can corrupt data if we don't wait
bit_delay_hi(); // attempt to fix corruption; unnecessary?
i2cm_start();
}
@ -121,11 +124,8 @@ void i2cm_stop()
{
SDA_OUTLO(); bit_delay_lo();
SCL_IN_HI(); bit_delay_hi();
while (!SCL_GET()); // clock stretch
SDA_IN_HI(); bit_delay_hi();
// wait some extra time
bit_delay_hi();
bit_delay_hi();
bit_delay_hi();
bit_delay_hi();
bit_delay_hi();

View File

@ -170,7 +170,7 @@ void i2cs_init(uint8_t address, uint8_t read_only_mode)
// enable interrupts
I2C1->CTLR2 |= I2C_CTLR2_ITBUFEN | I2C_CTLR2_ITEVTEN | I2C_CTLR2_ITERREN;
NVIC_SetPriority(I2C1_EV_IRQn, 1 << 6);
NVIC_SetPriority(I2C1_EV_IRQn, 0 << 6);
NVIC_EnableIRQ(I2C1_EV_IRQn); // Event interrupt
NVIC_SetPriority(I2C1_ER_IRQn, 3 << 6);
NVIC_EnableIRQ(I2C1_ER_IRQn); // Error interrupt
@ -192,7 +192,6 @@ void i2cs_poll()
}
//__attribute__((section(".ramfunc")))
__attribute__((interrupt("WCH-Interrupt-fast")))
void I2C1_EV_IRQHandler(void)
{

View File

@ -101,6 +101,7 @@ void systick_init(void)
SysTick->CTLR = 0xF; // start counter in /1 mode, enable interrupts, auto-reset counter
SysTick->SR = 0; // clear count comparison flag
NVIC_SetPriority(SysTicK_IRQn, 1 << 6);
NVIC_EnableIRQ(SysTicK_IRQn); // enable interrupt
}