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.

MSP430F2132: i2c slave

Part Number: MSP430F2132

Hello

Do you need external crystal for i2c 100kHz or 400kHz when using the eUSCI in slave mode


Thanks in advance
Stéphane

  • Short answer: No, the master provides the clocking. [Ref User Guide (SLAU144K) Sec 17.3.5]

    You may want to run the CPU at a reasonable speed (1MHz?) to assure responsiveness, but you don't need the clock accuracy of a crystal, the DCO will be fine.

  • Dear

    That is clear.
    I try to find  " MSP430F21x2 Code Examples (Rev. C): www.ti.com/.../slac163c "  but the link is wrong
    What is now the link ?


  • I just past and copy one of the examples in iRA 8.00 but i do not receive
     data

    What happens

    #include <msp430.h>
    ;-------------------------------------------------------------------------------
                RSEG    CSTACK                  ; Define stack segment
    ;-------------------------------------------------------------------------------
                RSEG    DATA16_N                ; RAM
    RxData      DS      128                     ; Allocate 128 byte of RAM
    ;-------------------------------------------------------------------------------
                RSEG    CODE                    ; Assemble to Flash memory
    ;-------------------------------------------------------------------------------
    RESET        mov.w   #SFE(CSTACK),SP         ; Initialize stackpointer
           //     dint
    StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT
    CheckCal    cmp.b   #0FFh,&CALBC1_16MHZ      ; Calibration constants erased?
                jeq     Trap
                cmp.b   #0FFh,&CALDCO_16MHZ
                jne     Load  
    Trap        jmp     $                       ; Trap CPU!!
    Load        mov.b   &CALBC1_16MHZ,&BCSCTL1   ; Set DCO to 16MHz
                mov.b   &CALDCO_16MHZ,&DCOCTL


    SetupP3     bis.b   #06h,&P3SEL             ; Assign I2C pins to USCI_B0
    SetupUCB0   bis.b   #UCSWRST,&UCB0CTL1      ; Enable SW reset
                mov.b   #UCMODE_3+UCSYNC,&UCB0CTL0
                                                ; I2C Slave, synchronous mode
                mov.w   #010h,&UCB0I2COA        ; Own Address is 010h
                bic.b   #UCSWRST,&UCB0CTL1      ; Clear SW reset, resume operation
                bis.b   #UCSTPIE+UCSTTIE,&UCB0I2CIE
                                                ; Enable STT and STP interrupt
               //  eint
                bis.b   #UCB0RXIE,&IE2          ; Enable RX interrupt

    Main        mov.w   #RxData,R5              ; Start of RX buffer
                clr.w   R6                      ; Clear RX byte count
            //    bis.b   #LPM0+GIE,SR            ; Enter LPM0, enable interrupts
                                                ; Remain in LPM0 until master
                                                ; finishes TX
                nop                             ; Set breakpoint >>here<< and
                                                ; read out the RxData buffer
                jmp     Main                    ; Repeat
    ;-------------------------------------------------------------------------------
    ; The USCI_B0 data ISR is used to move received data from the I2C master
    ; to the MSP430 memory.
    ;-------------------------------------------------------------------------------
    USCIAB0TX_ISR;      USCI_B0 Data ISR
    ;-------------------------------------------------------------------------------
                mov.b   &UCB0RXBUF,0(R5)        ; Move RX data to address R5
                inc.w   R5                      ; Increment address pointer
                inc.w   R6                      ; Increment RX byte count
                reti
    ;-------------------------------------------------------------------------------
    ; The USCI_B0 state ISR is used to wake up the CPU from LPM0 in order to
    ; process the received data in the main program. LPM0 is only exit in case
    ; of a (re-)start or stop condition when actual data was received.
    ;-------------------------------------------------------------------------------
    USCIAB0RX_ISR;      USCI_B0 State ISR
    ;-------------------------------------------------------------------------------
                bic.b   #UCSTPIFG+UCSTTIFG,&UCB0STAT
                                                ; Clear interrupt flags
                tst.w   R6                      ; Check RX byte counter
                jz      USCIAB0RX_ISR_1         ; Jump if nothing was received
            //    bic.w   #LPM0,0(SP)             ; Clear LPM0

    USCIAB0RX_ISR_1
                reti
    ;-------------------------------------------------------------------------------
                COMMON  INTVEC                  ; Interrupt Vectors
    ;-------------------------------------------------------------------------------
                ORG     USCIAB0TX_VECTOR        ; USCI_B0 I2C Data Int Vector
                DW      USCIAB0TX_ISR
                ORG     USCIAB0RX_VECTOR        ; USCI_B0 I2C Sate Int Vector
                DW      USCIAB0RX_ISR
                ORG     RESET_VECTOR            ; POR, ext. Reset, Watchdog
                DW      RESET
                END

  • How do you tell that it isn't receiving data? When you pause in the debugger, where is it executing?

    -----------------

    I don't have IAR, but it looks as though you modified these two lines:

    >        //    bis.b   #LPM0+GIE,SR            ; Enter LPM0, enable interrupts

    >       //    bic.w   #LPM0,0(SP)             ; Clear LPM0

    Removing them would prevent receiving data. I suggest you put these lines back.

  • i found the problem , the driver in IAR was the simulator i.e the FET debugger  :Confused

  • Dear

    i try to detect a repeated start as i2c slave.
    do you have an explantion of examples , how to proceed ?

  • Hi, 

    During transmission, if a start interrupt is triggered without a stop interrupt, that is a repeated start.

    Regards,

    Helic

  • Dear Helic

    Thanks for the quick response.
    Do you have same demo examples of this implementation.

  • Hi, 

    I didn't find demo code of this.

    Just set some kind of I2C_Status_flag variables in I2C interrupt is OK.

    Such as:

    void I2C_Start_interrupt_Handler(){
        if(I2C_STATUS_RX_STARTED){
            I2C_STATUS_RX_REPEATED_STARTED = true;
        }
        else{
            I2C_STATUS_RX_STARTED = true;
        }
    }
    
    void I2C_Stop_interrupt_Handler(){
            I2C_STATUS_RX_REPEATED_STARTED = false;
            I2C_STATUS_RX_STARTED = false;
            
            I2C_STATUS_RX_STOP = true;
    }
    

    Regards,

    Helic

  • Hello

    Just to inform that everythingg is working

    Best regards
    Stéphane.

**Attention** This is a public forum