This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

tiva-pirate: i2c slave interrupt

Hi again,

I'm gratified to see lots of i2c questions here on the forum. Fortunately there are some good examples of using master mode, especially polling the hardware. The search function becomes really useful for that.

I'm writing a Tiva i2c library because I have spent countless hours debugging the Tiva i2c hardware. I feel like I'm starting to achieve a good understanding of the master mode side of things, so I wanted to make that a package that can be reused by you all.

Slave mode is the missing piece. Yes, I can respond to I2C_SCSR_TREQ and the slave transmits fine. That's as far as I can get. Then I hit questions I can't seem to answer: (see the source code link at the bottom)

1. In example-isrnofifo.c: if I change i2c2.ti2cit.len = 0 to sizeof(write_buf) on line 109 then instead of just a QUICK_COMMAND it actually writes one byte before reading (using a repeated START). The slave controller never asserts I2C_SCSR_RREQ in either case, it just adds an additional I2C_SCSR_TREQ. This is probably the heart of the problem -- why am I getting 5 (or 6) TREQ instead of 1 (or 2) RREQ followed by 4 TREQ?

2. In example-isrnofifo.c: If I uncomment I2C_MIMR_STARTIM on line 223, the slave receives no interrupts other than STARTRIS.

3. In example-isrnofifo.c: If I uncomment I2C_MIMR_STOPIM on line 223, the slave receives no interrupts other than STOPRIS -- and it gets 2 STOPRIS when I am sure I am only sending one i2c STOP. (If both are unmasked then the slave receives one START and one STOP.)

4. In example-isrnofifo.c: The SCSR never sets QCMDST or QCMDRW, lines 305 and 320.

5. In example-isrnofifo.c: If I uncomment I2C_MCR_LPBK on line 215, just in case the problem is because I am using the device in loopback mode without setting that bit, I see no difference in the interrupt behavior. I do have a device which reports temperature on the bus, which is why I have been commenting out I2C_MCR_LPBK.

6. If I uncomment I2C_MCR_LPBK as above and also comment out GPIO_O_PUR) |= GPIO_PIN_0 | GPIO_PIN_1 in example-main.c line 102 I see no difference in the interrupt behavior.

Thanks in advance for helping me debug my i2c slave code!

Test cases uploaded to https://github.com/davidhubbard/tiva-ussh/tree/master/libti2cit - run the app then choose 2 from the menu presented on UART0 (2. Interrupts)

P.S. As to why I titled the post tiva-pirate: I'm definitely hoping to make this library the go-to solution for Tiva i2c code, including the tiva-pirate bus pirate clone.

  • While I still need help getting slave mode to work, does anyone with CCS want to try compiling this library? Let me know the output of the compiler.

  • Hello David,

    We appreciate such development especially when it comes back to the forum as well.. Thanks

    Before we begin; can you please visualize the test topology as to how you are connecting the I2C Master and the Slave if both are from the on-chip I2C. In limited form my answers below as I get the same on my side as well/

    #1: In regular I2C Mode the Quick Command cannot be done by putting the length to 0. Instead try using the MCS register write with the define I2C_MASTER_CMD_QUICK_COMMAND

    #2: Master Side Interrupt has got nothing to do with the Slave side (AFAIK) The Interrupt line is however shared. So you may want to query both the Master and Slave MIS registers.

    #4: Based on #1 can you let me know the results

    #5: The loopback is internal. You don't need to configure IO's also for this

    #6: Same as above.

    Regards

    Amit

  • Hi Amit,

    Here is the topology I'm using:

    Connected Launchpad
    TM4C1294NCPDT
    
    I2C #2    I2C #2
    master    slave
    SDA SCL   SDA SCL
     |   |     |   |
     |   +---------+
     |   |     |
     +---------+
     |   |
    PL0 PL1 (GPIO)
     |   |
     |   |
    SDA SCL
    Honeywell HIH-6121

    I'll try to explain each of my questions in more detail with respect to your comments:

    1. I might have phrased this better. Here's what I meant to say: the library libti2cit automatically switches between QUICK_COMMAND if you pass 0 for the len argument, and switches to SEND when you pass 1 for the len argument.

    Since the i2c2 slave sees the same thing as the pins PL0 and PL1, I can use a logic analyzer and watch the bus transaction. Note the slave address is 0x7f and I am requesting a read so the 8-bit address byte is 0xff.

    Line 109 has 0: START 0xff START read read read read

    Slave interrupts: TREQ TREQ TREQ TREQ TREQ

    Line 109 has 1: START 0xff 0x01 START read read read read

    Slave interrupts TREQ TREQ TREQ TREQ TREQ TREQ

    I don't understand why the slave interrupts aren't (QCMDST|QCMDRW) RREQ RREQ RREQ RREQ and TREQ RREQ RREQ RREQ? Or maybe it's something slightly different, but anything other than just all TREQ's?

    2. Please look at the code in example-isrnofifo.c lines 275-287 where I call the libti2cit_m_isr_isr() to check if this was a master interrupt, then I call libti2cit_s_isr_isr() to check if this was a slave interrupt.

    Then my original question: If I uncomment I2C_MIMR_STARTIM on line 223, the slave receives no interrupts other than STARTRIS.

    5. I will just try both I2C_MCR_LPBK and leaving it out because the slave interrupts still do not have anything other than TREQ.

    6. I will just try all combinations of I2C_MCR_LPBK and GPIO_O_PUR until the slave interrupts have something different than TREQ. Any information you can share will make this easier, but right now I am just so lost I am trying everything. :-)

    Thanks for your help!

  • In the attempt to "head off" needless difficulty & complication - may I suggest that this, "loopback" mode/method - with the sharing of I2C resources w/in the same MCU - is likely to prove, "sub-optimal."  Few years past - at another (large) semi firm - this was done - and whatever was "saved" was quickly "lost" due to the "shortcuts & other compromises" - too often dictated by any "I2C loopback" method.

    While loopback may prove quite successful w/UARTs - the added complexity imposed by I2C (especially the ACKs & NAKs - and of course the interrupts) tends to compromise results - and never quite, "carries over fully/properly" to the "real world implementation" of (separate) master & slave devices.

    As vendor Amit's post states, "The (I2C) Interrupt line is however shared (master & slave)."   That's a condition unlikely (i.e. never) to occur in a real world - multi-chip - I2C bus arrangement - thus exposing "loopback" as (at best) a compromised implementation - and (at worst) a false comfort. 

    Competent I2C Slave devices are numerous & inexpensive - the MCU as "kitchen sink" mania cannot match that reality...  A "real" MCU to "stand-alone" I2C Slave proves very much advantaged...

  • @cb1: Good idea. I'll try jumpering to a separate I2C controller and see if I can make some progress there.

    In the meantime, I'm happy to receive any suggestions.

  • Hello David,

    Thanks for the explanation on the topology.

    #1: The Quick Command is START => Slave Address => STOP. In this case it seems to be START => Slave Address => START which will not constitute a QUICK Command. Secondly, Do you see the LA doing a START => SLave Address => START or as you mentioned in the first post it put's a byte.

    #2-6: Good idea to have another TM4C board working only in Slave (Thanks cb1)...

    Regards

    Amit

  • Hi Amit,

    Sorry, I should have looked more carefully at my code. The code does the right thing. So I pass a 0 for len to the library, as you can see in the code, and then it correctly commands a RECEIVE_START which sends START 0xff START read read read read.

    For all questions 1-6, it sounds like loopback really doesn't work, yes?

  • Hi Amit,

    Two questions:

    1. Already asked -- loopback mode does not work, correct?

    2. I have created a minimum test case for enabling slave mode. It crashes just after writing to I2C_O_MCR. I'm using the code from Tivaware DriverLib here, I've just made it really clear where it crashes. Why does it crash? I end up in FaultISR with FAULTSTAT=0x00008200 and FAULTADDR=0x400c3020

    2538.example-main.c
    /* Copyright (c) 2014 David Hubbard github.com/davidhubbard
     * Licensed under the GNU LGPL v3.
     */
    
    #include <stdbool.h>
    #include <stdint.h>
    #include <stdio.h>
    #include "inc/hw_gpio.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_i2c.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/i2c.h"
    #include "driverlib/uart.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    
    void UARTsend(char * str)
    {
    	while (*str) {
    		ROM_UARTCharPut(UART0_BASE, *str++);
    	}
    }
    
    
    
    // select who receives i2c interrupts. Note: The hardware can do this for you in the NVIC, much faster.
    void i2c2IntHandler()
    {
    	UARTsend("i2c2 Int\r\n");
    }
    void i2c7IntHandler()
    {
    	UARTsend("i2c7 Int\r\n");
    }
    
    
    int main(void) {
    	uint32_t sysclock;
    	do {
    		sysclock = ROM_SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120*1000*1000);
    	} while (!sysclock);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    	while (!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_I2C2)) ;
    	while (!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD)) ;
    	while (!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)) ;
    	while (!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_UART0)) ;
    	ROM_GPIOPinConfigure(GPIO_PD1_I2C7SDA);
    	ROM_GPIOPinConfigure(GPIO_PD0_I2C7SCL);
    	ROM_GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);
    	ROM_GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);
    
    	ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    	ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    	ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    	ROM_UARTConfigSetExpClk(UART0_BASE, sysclock, 115200,
    		UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
    
    	UARTsend("about to set MCR\r\n");
    	HWREG(I2C7_BASE + I2C_O_MCR) |= I2C_MCR_SFE;
    	UARTsend("about to set SCSR\r\n");
    	HWREG(I2C7_BASE + I2C_O_SCSR) = I2C_SCSR_DA;
    	UARTsend("about to set SOAR\r\n");
    	HWREG(I2C7_BASE + I2C_O_SOAR) = 0x7f;
    	UARTsend("done\r\n");
    
    	for(;;);
    }
    

    4540.startup_gcc.c
    /* Copyright (c) 2014 David Hubbard github.com/davidhubbard
     * Example startup file for tiva-ussh libti2cit example.
     * Licensed under the GNU LGPL v3.
     *
     * The most common reason you would need to edit this file is to add or change an
     * interrupt handler. Declare the ISR just like the other functions defined here.
     */
    
    #include <stdint.h>
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    
    /*
     * Interrupt Service Routines (ISR's) must return void and must take no arguments.
     */
    typedef void (* const int_vector_t)();
    
    
    /*
     * 90% of the time you want to declare your ISR extern and then put it in a
     * different .c file.
     */
           void ResetISR();
    static void NmiSR();
    static void FaultISR();
    static void IntDefaultHandler();
    extern void i2c2IntHandler();
    extern void i2c7IntHandler();
    
    
    
    /*
     * The int_vector_table[] is directly read by the CPU when it handles an interrupt.
     *
     * List your ISR here to get your code executed when that particular interrupt fires.
     */
    
    static uint32_t app_stack[64];                  // The initial stack pointer
    __attribute__ ((section(".isr_vector"))) int_vector_t int_vector_table[] =
    {
    	(int_vector_t)((uint32_t)app_stack + sizeof(app_stack)), // 0: stack pointer
    	ResetISR,                               //   1: The reset handler
    	NmiSR,                                  //   2: The NMI handler
    	FaultISR,                               //   3: The hard fault handler
    	IntDefaultHandler,                      //   4: The MPU fault handler
    	IntDefaultHandler,                      //   5: The bus fault handler
    	IntDefaultHandler,                      //   6: The usage fault handler
    	0,                                      //   7: Reserved
    	0,                                      //   8: Reserved
    	0,                                      //   9: Reserved
    	0,                                      //  10: Reserved
    	IntDefaultHandler,                      //  11: SVCall handler
    	IntDefaultHandler,                      //  12: Debug monitor handler
    	0,                                      //  13: Reserved
    	IntDefaultHandler,                      //  14: The PendSV handler
    	IntDefaultHandler,                      //  15: The SysTick handler
    	IntDefaultHandler,                      //  16: GPIO Port A
    	IntDefaultHandler,                      //  17: GPIO Port B
    	IntDefaultHandler,                      //  18: GPIO Port C
    	IntDefaultHandler,                      //  19: GPIO Port D
    	IntDefaultHandler,                      //  20: GPIO Port E
    	IntDefaultHandler,                      //  21: UART0 Rx and Tx
    	IntDefaultHandler,                      //  22: UART1 Rx and Tx
    	IntDefaultHandler,                      //  23: SSI0 Rx and Tx
    	IntDefaultHandler,                      //  24: I2C0 Master and Slave
    	IntDefaultHandler,                      //  25: PWM Fault
    	IntDefaultHandler,                      //  26: PWM Generator 0
    	IntDefaultHandler,                      //  27: PWM Generator 1
    	IntDefaultHandler,                      //  28: PWM Generator 2
    	IntDefaultHandler,                      //  29: Quadrature Encoder 0
    	IntDefaultHandler,                      //  30: ADC Sequence 0
    	IntDefaultHandler,                      //  31: ADC Sequence 1
    	IntDefaultHandler,                      //  32: ADC Sequence 2
    	IntDefaultHandler,                      //  33: ADC Sequence 3
    	IntDefaultHandler,                      //  34: Watchdog timer
    	IntDefaultHandler,                      //  35: Timer 0 subtimer A
    	IntDefaultHandler,                      //  36: Timer 0 subtimer B
    	IntDefaultHandler,                      //  37: Timer 1 subtimer A
    	IntDefaultHandler,                      //  38: Timer 1 subtimer B
    	IntDefaultHandler,                      //  39: Timer 2 subtimer A
    	IntDefaultHandler,                      //  40: Timer 2 subtimer B
    	IntDefaultHandler,                      //  41: Analog Comparator 0
    	IntDefaultHandler,                      //  42: Analog Comparator 1
    	IntDefaultHandler,                      //  43: Analog Comparator 2
    	IntDefaultHandler,                      //  44: System Control (PLL, OSC, BO)
    	IntDefaultHandler,                      //  45: FLASH Control
    	IntDefaultHandler,                      //  46: GPIO Port F
    	IntDefaultHandler,                      //  47: GPIO Port G
    	IntDefaultHandler,                      //  48: GPIO Port H
    	IntDefaultHandler,                      //  49: UART2 Rx and Tx
    	IntDefaultHandler,                      //  50: SSI1 Rx and Tx
    	IntDefaultHandler,                      //  51: Timer 3 subtimer A
    	IntDefaultHandler,                      //  52: Timer 3 subtimer B
    	IntDefaultHandler,                      //  53: I2C1 Master and Slave
    	IntDefaultHandler,                      //  54: CAN0 (TM4C123 Quadrature Encoder 1)
    	IntDefaultHandler,                      //  55: CAN1 (TM4C123 CAN0)
    	IntDefaultHandler,                      //  56: Ethernet (TM4C123 CAN1)
    	IntDefaultHandler,                      //  57: HIB
    	IntDefaultHandler,                      //  58: USB MAC
    	IntDefaultHandler,                      //  59: PWM Generator 3 (TM4C123 Hibernate)
    	IntDefaultHandler,                      //  60: uDMA 0 Software (TM4C123 USB0)
    	IntDefaultHandler,                      //  61: uDMA 0 Error (TM4C123 PWM Generator 3)
    	IntDefaultHandler,                      //  62: ADC1 Seq0 (TM4C123 uDMA Software Transfer)
    	IntDefaultHandler,                      //  63: ADC1 Seq1 (TM4C123 uDMA Error)
    	IntDefaultHandler,                      //  64: ADC1 Seq2 (TM4C123 ADC1 Sequence 0)
    	IntDefaultHandler,                      //  65: ADC1 Seq3 (TM4C123 ADC1 Sequence 1)
    	IntDefaultHandler,                      //  66: EPI 0     (TM4C123 ADC1 Sequence 2)
    	IntDefaultHandler,                      //  67: GPIO Port J (TM4C123 ADC1 Sequence 3)
    	0,                                      //  68: GPIO Port K
    	0,                                      //  69: GPIO Port L
    	IntDefaultHandler,                      //  70: SSI 2 (TM4C123 GPIO Port J)
    	IntDefaultHandler,                      //  71: SSI 3 (TM4C123 GPIO Port K)
    	IntDefaultHandler,                      //  72: UART 3 (TM4C123 GPIO Port L)
    	IntDefaultHandler,                      //  73: UART 4 (TM4C123 SSI2 Rx and Tx)
    	IntDefaultHandler,                      //  74: UART 5 (TM4C123 SSI3 Rx and Tx)
    	IntDefaultHandler,                      //  75: UART 6 (TM4C123 UART3 Rx and Tx)
    	IntDefaultHandler,                      //  76: UART 7 (TM4C123 UART4 Rx and Tx)
    	i2c2IntHandler,                         //  77: I2C2 (TM4C123 UART5 Rx and Tx)
    	IntDefaultHandler,                      //  78: I2C3 (TM4C123 UART6 Rx and Tx)
    	IntDefaultHandler,                      //  79: Timer 4A (TM4C123 UART7 Rx and Tx)
    	0,                                      //  80: Timer 4B
    	0,                                      //  81: Timer 5A
    	0,                                      //  82: Timer 5B
    	0,                                      //  83: Floating-Point Exception "imprecise"
    	IntDefaultHandler,                      //  84: (TM4C123 I2C2 Master and Slave)
    	IntDefaultHandler,                      //  85: (TM4C123 I2C3 Master and Slave)
    	IntDefaultHandler,                      //  86: I2C4 (TM4C123 Timer 4 subtimer A)
    	IntDefaultHandler,                      //  87: I2C5 (TM4C123 Timer 4 subtimer B)
    	0,                                      //  88: GPIO Port M
    	0,                                      //  89: GPIO Port N
    	0,                                      //  90:
    	0,                                      //  91: Tamper
    	0,                                      //  92: GPIO Port P "Summary or P0"
    	0,                                      //  93: GPIO Port P1
    	0,                                      //  94: GPIO Port P2
    	0,                                      //  95: GPIO Port P3
    	0,                                      //  96: GPIO Port P4
    	0,                                      //  97: GPIO Port P5
    	0,                                      //  98: GPIO Port P6
    	0,                                      //  99: GPIO Port P7
    	0,                                      // 100: GPIO Port Q "Summary or Q0"
    	0,                                      // 101: GPIO Port Q1
    	0,                                      // 102: GPIO Port Q2
    	0,                                      // 103: GPIO Port Q3
    	0,                                      // 104: GPIO Port Q4
    	0,                                      // 105: GPIO Port Q5
    	0,                                      // 106: GPIO Port Q6
    	0,                                      // 107: GPIO Port Q7
    	IntDefaultHandler,                      // 108: GPIO Port R (TM4C123 Timer 5 subtimer A)
    	IntDefaultHandler,                      // 109: GPIO Port S (TM4C123 Timer 5 subtimer B)
    	IntDefaultHandler,                      // 110: SHA/MD5 (TM4C123 Wide Timer 0 subtimer A)
    	IntDefaultHandler,                      // 111: AES (TM4C123 Wide Timer 0 subtimer B)
    	IntDefaultHandler,                      // 112: DES (TM4C123 Wide Timer 1 subtimer A)
    	IntDefaultHandler,                      // 113: LCD (TM4C123 Wide Timer 1 subtimer B)
    	IntDefaultHandler,                      // 114: 16/32-Bit Timer 6A (TM4C123 Wide Timer 2 subtimer A)
    	IntDefaultHandler,                      // 115: 16/32-Bit Timer 6B (TM4C123 Wide Timer 2 subtimer B)
    	IntDefaultHandler,                      // 116: 16/32-Bit Timer 7A (TM4C123 Wide Timer 3 subtimer A)
    	IntDefaultHandler,                      // 117: 16/32-Bit Timer 7B (TM4C123 Wide Timer 3 subtimer B)
    	IntDefaultHandler,                      // 118: I2C6 (TM4C123 Wide Timer 4 subtimer A)
    	i2c7IntHandler,                         // 119: I2C7 (TM4C123 Wide Timer 4 subtimer B)
    	IntDefaultHandler,                      // 120: (TM4C123 Wide Timer 5 subtimer A)
    	IntDefaultHandler,                      // 121: 1-Wire (TM4C123 Wide Timer 5 subtimer B)
    	IntDefaultHandler,                      // 122: (TM4C123 FPU)
    	IntDefaultHandler,                      // 123: (TM4C123 PECI 0)
    	IntDefaultHandler,                      // 124: (TM4C123 LPC 0)
    	IntDefaultHandler,                      // 125: I2C8 (TM4C123 I2C4 Master and Slave)
    	IntDefaultHandler,                      // 126: I2C9 (TM4C123 I2C5 Master and Slave)
    	IntDefaultHandler,                      // 127: GPIO Port T (TM4C123 GPIO Port M)
    	IntDefaultHandler,                      // 128: (TM4C123 GPIO Port N)
    #if 0
    /*These are only defined for the TM4C123*/
    
    	IntDefaultHandler,                      // 129: (TM4C123 Quadrature Encoder 2)
    	IntDefaultHandler,                      // 130: (TM4C123 Fan 0)
    	0,                                      // 131:
    	IntDefaultHandler,                      // 132: (TM4C123 GPIO Port P (Summary or P0))
    	IntDefaultHandler,                      // 133: (TM4C123 GPIO Port P1)
    	IntDefaultHandler,                      // 134: (TM4C123 GPIO Port P2)
    	IntDefaultHandler,                      // 135: (TM4C123 GPIO Port P3)
    	IntDefaultHandler,                      // 136: (TM4C123 GPIO Port P4)
    	IntDefaultHandler,                      // 137: (TM4C123 GPIO Port P5)
    	IntDefaultHandler,                      // 138: (TM4C123 GPIO Port P6)
    	IntDefaultHandler,                      // 139: (TM4C123 GPIO Port P7)
    	IntDefaultHandler,                      // 140: (TM4C123 GPIO Port Q (Summary or Q0))
    	IntDefaultHandler,                      // 141: (TM4C123 GPIO Port Q1)
    	IntDefaultHandler,                      // 142: (TM4C123 GPIO Port Q2)
    	IntDefaultHandler,                      // 143: (TM4C123 GPIO Port Q3)
    	IntDefaultHandler,                      // 144: (TM4C123 GPIO Port Q4)
    	IntDefaultHandler,                      // 145: (TM4C123 GPIO Port Q5)
    	IntDefaultHandler,                      // 146: (TM4C123 GPIO Port Q6)
    	IntDefaultHandler,                      // 147: (TM4C123 GPIO Port Q7)
    	IntDefaultHandler,                      // 148: (TM4C123 GPIO Port R)
    	IntDefaultHandler,                      // 149: (TM4C123 GPIO Port S)
    	IntDefaultHandler,                      // 150: (TM4C123 PWM 1 Generator 0)
    	IntDefaultHandler,                      // 151: (TM4C123 PWM 1 Generator 1)
    	IntDefaultHandler,                      // 152: (TM4C123 PWM 1 Generator 2)
    	IntDefaultHandler,                      // 153: (TM4C123 PWM 1 Generator 3)
    	IntDefaultHandler                       // 154: (TM4C123 PWM 1 Fault)
    #endif
    };
    
    extern uint32_t _etext;
    extern uint32_t _data;
    extern uint32_t _edata;
    extern uint32_t _bss;
    extern uint32_t _ebss;
    
    extern int main();
    
    void ResetISR(void)
    {
    	// 167: copy _data from flash to ram
    	uint32_t *src = &_etext;
    	uint32_t *dst;
    	for (dst = &_data; dst < &_edata; ) *dst++ = *src++;
    
    	// 172: the compiler demands the bss section must be zero after each reset
    	__asm("		ldr     r0, =_bss"
    	 "\n		ldr     r1, =_ebss"
    	 "\n		mov     r2, #0"
    	 "\n		.thumb_func"
    	 "\n	zero_loop:"
    	 "\n		cmp     r0, r1"
    	 "\n		it      lt"
    	 "\n		strlt   r2, [r0], #4"
    	 "\n		blt     zero_loop");
    
    	// 183: enable fpu before calling main() -- note that this is the proper
    	// 184: place to change any fpu configs
    	HWREG(NVIC_CPAC) = ((HWREG(NVIC_CPAC) &
    		 ~(NVIC_CPAC_CP10_M | NVIC_CPAC_CP11_M)) |
    		NVIC_CPAC_CP10_FULL | NVIC_CPAC_CP11_FULL);
    
    	main();
    }
    
    static void NmiSR()
    {
    	for (;;) ;
    }
    
    static void FaultISR()
    {
    	for (;;) ;
    }
    
    static void IntDefaultHandler()
    {
    	for (;;) ;
    }
    

  • Hello David,

    1. Loopback mode works. Only that when in loopback mode using the I2C register the external inputs would not be considered.

    2. The peripheral being accessed is I2C7 but the clock is being enabled for I2C2.

    Regards

    Amit

  • Hi Amit,

    Thanks for those answers. I've uploaded an updated version of the test case to https://github.com/davidhubbard/tiva-ussh/tree/master/libti2cit. As cb1 suggested, I've jumpered from PL0-PD1 and PL1-PD0. (They're adjacent on Boosterpack 1.)

    Here's the output, which is not what I expected:

    Choice: 2
    .s_START: starting
    s_STOP: stopped
    ........[snip].....gave up, took too long

    What it should look like (for you, without the i2c temp sensor on the bus, just the i2c7 slave):

    Choice: 2
    ..............[7f]s_TREQ status=0001 RIS
    s_TREQ status=0001 RIS
    s_TREQ status=0001 RIS
    s_TREQ status=0001 RIS
    s_TREQ status=0001 RIS
     00010203
    temp=-3.87 C -3.76 F
    .done

    Edit: In a previous post I wrote without looking and said RREQ. Changed that to TREQ now.

  • Hello David,

    I would need to reconstruct the code for independent Master and Slave instances of I2C in my own setup but with the LaunchPad. That would not be a trivial task but would help cross-correlate with what you have.

    Regards

    Amit

  • I have two launchpads here. I'll try to make an independent slave version, if I understand what you're trying to do?

    Do you just want a version with all the i2c master code commented out so it doesn't run?

  • Hello David,

    From HW perspective yes, that is what I want to do. From a SW perspective I will stick to TivaWare and CCS as it adds to the repository and can be useful during debug.

    Regards

    Amit

  • Ok, no problem if you use TivaWare and CCS.

    Here is the project stripped down to just the slave:4503.just-slave.zip

  • Just checking, Amit, did the version with just the slave compile ok for you? Have you had a chance to look into the interrupts problem?

  • Hello David,

    Did not get time last week and seems tough to get is closed. But I have it on my list of to-do (massive when a long weekend comes along)

    Regards

    Amit

  • Ok. No worries! I understand the busy season.

  • Hi Amit,

    I'm curious if you've had a chance to take a look?
  • Hello David,

    Working on the same :-). Takes me time to get the wiring and pull's right on the setup.

    Regards
    Amit
  • This Tiva-Pirate seems (so often to run aground) may prove as "seaworthy" as Blackbeard's.   (and his was cannon-shot...)

    Are we not trying to, "Reinvent the wheel" at the cost of Amit's time/effort/other demands...  And - should this be a, "high priority?"

  • @cb1:

    Absolutely! The goal here is to reduce the number of i2c questions by letting users grab several i2c examples from tiva-pirate.
  • @David,

    Good - yet you seem impaled on the very complex handling of MCU as "Slave" - and that's a very minority use for most here...

    To many here - Amit's gone above/beyond (as have you) but such "fine detail" (especially while this NEW, HIGH TIDE) befalls the forum - may be unreasonable...

    And - even if/when you finally succeed - vendor has proved incapable of adequately highlighting such, "Key, critical data!   (as exhibit "A" may I present dreaded PF0, PD7, 0-ohm Rs etc - they continue to plague/impale hapless users - do they not?)

    How will users "even find" this "pirate" should it escape flood tide forum change & on-going, Slave, "back-forth?"

  • Hello cb1

    Appreciate your support on the same. However if the TivaWare has more representive code instead of loopback wouldn't the forum and community benefit as well.

    Regards
    Amit
  • Hello Amit,

    More representative code is always good - yet NOT at the sacrifice of more needed code - and multiple (long lingering) items in need of FIXES!

    We realize you're one guy - a vastly skilled & dedicated guy - and in "going public" we learned that, "Dilution of critical resources" is not best/brightest use of a scarce resource!

    Should not a, "Priority List" be generated - and items attacked from that?  As stated - Slave MCU I2C usage is, "in the noise" - is it not?  How many "back/forth" posts will (or can) satisfy? 

    David's made a valiant effort - but to "grab your time/attention" - especially w/these forum change issues raining down upon you - proves a, "thorn in your side."  (even though you'll not admit that)

    And - as stated - if users' cannot find, "PF0/PD7 - 0-ohm Rs - & SysCtlGet() traps"  how ever do we expect them to find, (and understand) the overly cryptic, Tiva Pirate?  (I.e. what's I2C - and what's a Pirate?...)

  • I'm still interested in getting slave mode to work with interrupts. Any tips?