Sorry to hijack thread, but given the purpose of the I2C Interupt in this thread was to get I2C + SPI working together, seemed relevant. Shout if you want it moved to a dedicated debug thread...
Simple test harness code - SPI/MMC works perfectly if I2C is stopped before MMC functions.
Explanation: If you comment i2cstop in the following section, SPI functions fail.
Code: Select all
// If I2C remains enabled, SPI functions will not work
// If i2cStop called, SPI Functions operate correctly
i2cStop(&I2CD2);
If you leave it un-commented then you are able to enable I2C and perform the operation as long as you disable I2C before SPI operation. See commented block below ...
Code: Select all
/*
* If this block is enabled, function operates normally as i2cStop called before next SPI operation
i2cStart(&I2CD2, &i2cfg1);
// Interupt mode = Single byte read working fine, actually 2 byte read never completes - no stop bits
// If i2cStop called, SPI Functions operate correctly
retcode = i2cMasterTransmitTimeout(&I2CD2, addr, txbuf, 1, rxbuf, 1, 10 );
if (retcode == RDY_OK) {
chprintf((BaseSequentialStream*) &SD3, "I2C MPU6050 Detected on I2C2 - ID : 0x%x\n\r", rxbuf[0]);
}
// If I2C remains enabled, SPI functions will not work
i2cStop(&I2CD2);
*/
Full debugging code block for main.c ( with I2C2 enabled, SPI2 Enabled, USARTS3 Enabled ):
Code: Select all
/* Debug I2c Interupt + SPI Concurrent */
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include "ff.h"
#define MPU6050_WHO_AM_I 0x75 // R
static const I2CConfig i2cfg1 = {
OPMODE_I2C,
360000,
FAST_DUTY_CYCLE_16_9,
};
/* MMC/SD over SPI driver configuration.*/
MMCDriver MMCD1;
static SPIConfig hs_spicfg = {NULL, GPIOB, SD_SPI_CS, 0}; /* Maximum speed SPI configuration (18MHz, CPHA=0, CPOL=0, MSb first).*/
static SPIConfig ls_spicfg = {NULL, GPIOB, SD_SPI_CS, SPI_CR1_BR_2 | SPI_CR1_BR_1}; /* Low speed SPI configuration (281.250kHz, CPHA=0, CPOL=0, MSb first).*/
static MMCConfig mmccfg = {&SPID2, &ls_spicfg, &hs_spicfg};
FATFS MMC_FS;
FIL fdst;
static bool_t fs_ready = FALSE;
static char fbuff[512];
int main(void) {
FRESULT err;
char buff[100]; // f_read data buffer
uint8_t txbuf[2];
uint8_t rxbuf[2];
msg_t retcode = 1;
unsigned int bw;
int addr = 0b1101000; // MPU6050 Device Address
txbuf[0] = MPU6050_WHO_AM_I; // WhoAmI Register Address
halInit();
chSysInit();
sdStart(&SD1, NULL);
sdStart(&SD3, NULL);
chprintf((BaseSequentialStream*) &SD3, "\x1b[2J\rStarting Debug of I2C ...\n\r");
i2cInit();
i2cStart(&I2CD2, &i2cfg1);
// If I2C remains enabled, SPI functions will not work
// If i2cStop called, SPI Functions operate correctly
i2cStop(&I2CD2);
mmcObjectInit(&MMCD1);
mmcStart(&MMCD1, &mmccfg);
fs_ready = FALSE;
if (!mmcConnect(&MMCD1)) {
err = f_mount(0, &MMC_FS);
if (err != FR_OK) {
mmcDisconnect(&MMCD1);
} else {
fs_ready = TRUE;
}
}
if (fs_ready){
// err used in debugger only - not worth coding nice output
err=f_open(&fdst, "0:/RaceData/racedata.dat", FA_CREATE_ALWAYS | FA_WRITE);
err=f_write(&fdst, "Hello World read back from DataFile\n\r", 37, &bw);
err=f_sync(&fdst);
err=f_close(&fdst);
}
// Loop forever reading contents of file and sending to SD3 Serial
// Or fail if I2C not stopped
while(1)
{
/*
* If this block is enabled, function operates normally as i2cStop called before next SPI operation
i2cStart(&I2CD2, &i2cfg1);
// Interupt mode = Single byte read working fine, actually 2 byte read never completes - no stop bits
// If i2cStop called, SPI Functions operate correctly
retcode = i2cMasterTransmitTimeout(&I2CD2, addr, txbuf, 1, rxbuf, 1, 10 );
if (retcode == RDY_OK) {
chprintf((BaseSequentialStream*) &SD3, "I2C MPU6050 Detected on I2C2 - ID : 0x%x\n\r", rxbuf[0]);
}
// If I2C remains enabled, SPI functions will not work
i2cStop(&I2CD2);
*/
if (fs_ready) {
err=f_open(&fdst, "0:/RaceData/racedata.dat", FA_OPEN_ALWAYS | FA_READ);
if (err == FR_OK)
{
int pos=0;
int fsize = f_size(&fdst);
while ((pos<fsize) && (err == FR_OK))
{
err = f_read(&fdst, &buff[0], 100, &bw);
buff[bw] = 0;
if (bw > 0) chprintf((BaseSequentialStream*) &SD3, "%s", &buff);
pos+=bw;
}
f_close(&fdst);
} else {
chprintf((BaseSequentialStream*) &SD3, "Failed to open file\n\r");
}
} else {
chprintf((BaseSequentialStream*) &SD3, "Filesystem not ready\n\r");
}
}
}
Sorry for using the FF Lib for SPI, but it was already compiled into my project and the easiest way to trigger SPI.
Any thoughts / things I could try.