Part Number:MSP432P401R
I must be missing something simple. But I cannot get the void EUSCIB0_IRQHandler(void) when in slave mode and data is coming in.
This is the setup. /* Select Port 1 for I2C - Set Pin 6, 7 to input Primary Module Function, * (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL). */ MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION); /* eUSCI I2C Slave Configuration */ MAP_I2C_initSlave(EUSCI_B0_BASE, I2C1_SLAVE_ADDR, EUSCI_B_I2C_OWN_ADDRESS_OFFSET0, EUSCI_B_I2C_OWN_ADDRESS_ENABLE); /* Set in receive mode */ MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE); //MAP_I2C_registerInterrupt(EUSCI_B0_BASE,EUSCIB0_IRQHandler); /* Enable the module and enable interrupts */ MAP_I2C_enableModule(EUSCI_B0_BASE); MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, 0xFF); MAP_I2C_enableInterrupt(EUSCI_B0_BASE, 0xFF); //MAP_I2C_enableInterrupt(EUSCI_B0_BASE, 0xFF); MAP_Interrupt_enableSleepOnIsrExit(); MAP_Interrupt_enableInterrupt(INT_EUSCIB0); MAP_Interrupt_enableMaster(); and this is the ISR
void EUSCIB0_IRQHandler(void) { add_trace(0xFF); // so we know we started a new interrupt add_trace(UCB0IV); switch(UCB0IV) { case 0x00: // No interrupt pending break; case 0x02: // Arbitration lost; Interrupt Flag: UCALIFG; Interrupt Priority: Highest break; case 0x04: // Not acknowledgment; Interrupt Flag: UCNACKIFG break; case 0x06: // Start condition received; Interrupt Flag: UCSTTIFG // Initialize everything if this is first start if (start_state == 0) // Initial Start { start_state = 1; receive_state = 0; // Should get the command next I2C_Host_Receive_Byte = 0; I2C_Host_Byte = 0; Host_Error = 0; write_command = 0; // not sure yet, so assume read, change when confirmed write Host_Index = 0; // Probably not needed to initialize when working Host_Command = 0; // Probably not needed to initialize when working } else // Restart { start_state = 0; // Only 1 Restart assumed I2C_HOST->TXBUF = host_string_to_send[0]; // First Character out; I2C_Host_Byte = 1; } break; case 0x08: // Stop condition received; Interrupt Flag: UCSTPIFG // if write command update memory if PEC O.K. if (write_command == 1) { uint16_t i; // verify Host_Command is one we can write for (i=0;i<MAX_HOST_WRITE_COMMANDS_INDEX;i++) { if (host_write_command_list[i] == Host_Command) { uint8_t PEC = crc8_step(0, Host_Command); PEC = crc8_step(PEC, host_string_received[0]); PEC = crc8_step(PEC, host_string_received[1]); if (host_string_received[2] == PEC) // everything is valid { // move data from string to where structure points to uint8_t * po = (uint8_t *) host_structure[Host_Index].data_pointer; *po = host_string_received[0]; po++; *po = host_string_received[1]; // moved add_trace(0); } else { Host_Error = 1; // Bad PEC add_trace(1); } } else { Host_Error = 2; // Bad Write Command add_trace(2); } } } // Done reset everything start_state = 0; receive_state = 0; add_trace(0xFE); // end break; case 0x0A: // Slave 3 Data received; Interrupt Flag: UCRXIFG3 break; case 0x0C: // Slave 3 Transmit buffer empty; Interrupt Flag:UCTXIFG3 break; case 0x0E: // Slave 2 Data received; Interrupt Flag: UCRXIFG2 break; case 0x10: // Slave 2 Transmit buffer empty; Interrupt Flag: UCTXIFG2 break; case 0x12: // Slave 1 Data received; Interrupt Flag: UCRXIFG1 break; case 0x14: // Slave 1 Transmit buffer empty; Interrupt Flag: UCTXIFG1 break; case 0x16: // Data received; Interrupt Flag: UCRXIFG0 if (receive_state == 0) // first byte. { Host_Command = I2C_HOST->RXBUF; // Assume it is for a read command because it is most time critical. Host_Index = host_structure_lookup[Host_Command]; // fastest lookup/more space if (Host_Index > 0) // valid command -- bad command = -1 { if (host_structure[Host_Index].length == 2) // read word format { uint8_t *po; uint8_t *pi; uint8_t i; I2C1_Bytes_to_Send = 3; // word + PEC po = I2C1_Data_ptr = host_string_to_send; pi = (uint8_t *) host_structure[Host_Index].data_pointer; i = 2; while (i > 0) { *po++ = *pi++; // verify incrementing address not value in addreess i--; } { uint8_t PEC = 0; PEC = crc8_step(PEC, host_string_to_send[0]); host_string_to_send[2] = crc8_step(PEC, host_string_to_send[1]); // PEC } host_string_to_send[3] = 0; // not needed but to be safe } else // block read format which has size as first byte. { uint8_t PEC; uint8_t *po; uint8_t *pi; uint8_t i = host_structure[Host_Index].length; I2C1_Bytes_to_Send = i + 2; // count + data + PEC po = I2C1_Data_ptr = host_string_to_send; *po = i + 1; // length to send data + PEC PEC = crc8_step(0, host_string_to_send[0]); po++; // increment pointer address pi = (uint8_t *) host_structure[Host_Index].data_pointer; while (i > 0) { *po = *pi++; PEC = crc8_step(PEC, *po); po++; i--; } *po++ = PEC; // PEC *po = 0; // not needed but to be safe } } else // not valid command { I2C1_Bytes_to_Send = 3; // count + data + PEC I2C1_Data_ptr = host_string_to_send; host_string_to_send[0] = 0; host_string_to_send[1] = 0; host_string_to_send[2] = crc8(host_string_to_send, 2); // PEC -> should be a constant, find what it is, do not calculate. host_string_to_send[3] = 0; // not needed but to be safe } receive_state = 1; } else if (receive_state == 1) // more bytes to read, must be a write command { write_command = 1; host_string_received[I2C_Host_Receive_Byte] = I2C_HOST->RXBUF; I2C_Host_Receive_Byte++; } break; case 0x18: // Transmit buffer empty; Interrupt Flag: UCTXIFG0 I2C_HOST->TXBUF = host_string_to_send[I2C_Host_Byte]; // Next Character out; I2C_Host_Byte++; break; case 0x1A: // Byte counter zero; Interrupt Flag: UCBCNTIFG break; case 0x1C: // Clock low timeout; Interrupt Flag: UCCLTOIFG break; case 0x1E: // 9th bit position; Interrupt Flag: UCBIT9IFG; Priority: Lowest break; } }
Bottom line is that the interrupt code is never executed.
It has to be missing something in the setup.
I sent a read word I2C SMBus message.
Based on my experience with the MSP430, I think should have an interrupt for Start, Data Received (address), and the Restart. to this point where it is waiting for me to respond.
The ISR was never called.
That tells me I am missing something in the setup. But I do not know what.
Any ideas?
How does the interrupt controller know that EUSCIB0_IRQHandler is my ISR?
Is it because it is a reserved name for that ISR? Or do I have to map it somehow? I want it to be a static mapping.
I am using the IAR compiler.