Question
I2C Slave
Posted on May 17, 2015 at 21:28
I've been trying to work out how to make the STM8S act as an I2C slave and to be honest I'm failing. I think I've set everything up according to the reference manual but for some reason I'm not getting the expected interrupts being fired.
I have a Netduino setup as an I2C master. The logic analyser and the scope both show a write and an address of 0x02 and a NAK being generated on the I2C bus.I was expecting the STM8S to generate an ACK and an interrupt to request data or to send data. At the very least I was expecting an interrupt to be generated.I know the interrupt handler is being wired up as I get an error interrupt when I recompile the Netduino code and it redeploys. At this time it messes up the I2C bus.The STM8S application code is:#include <iostm8s103f3.h>#include <intrinsics.h>//// I2C interrupts all share the same handler.//#pragma vector = I2C_RXNE_vector__interrupt void I2C_IRQHandler(){ if (I2C_SR1_RXNE) { unsigned char data; data = I2C_DR; } if (I2C_SR1_TXE) { I2C_DR = 0xaa; // Some dummy data to send. }}//// Setup the system clock.//void InitialiseSystemClock(){ CLK_ICKR = 0; // Reset the Internal Clock Register. CLK_ICKR_HSIEN = 1; // Enable the HSI. CLK_ECKR = 0; // Disable the external clock. while (CLK_ICKR_HSIRDY == 0); // Wait for the HSI to be ready for use. CLK_CKDIVR = 0; // Ensure the clocks are running at full speed. CLK_PCKENR1 = 0xff; // Enable all peripheral clocks. CLK_PCKENR2 = 0xff; // Ditto. CLK_CCOR = 0; // Turn off CCO. CLK_HSITRIMR = 0; // Turn off any HSIU trimming. CLK_SWIMCCR = 0; // Set SWIM to run at clock / 2. CLK_SWR = 0xe1; // Use HSI as the clock source. CLK_SWCR = 0; // Reset the clock switch control register. CLK_SWCR_SWEN = 1; // Enable switching. while (CLK_SWCR_SWBSY != 0); // Pause while the clock switch is busy.}//// Setup I2C.//void InitialiseI2C(){ I2C_CR1_PE = 0; // Diable I2C before configuration starts. // // Setup the clock information. // I2C_FREQR = 16; // Set the internal clock frequency (MHz). I2C_CCRH_F_S = 0; // I2C running is standard mode. I2C_CCRL = 0xa0; // SCL clock speed is 50 KHz. I2C_CCRH_CCR = 0x00; // // Set the address of this device. // I2C_OARL_ADD = 0x02; // Seven bit address. I2C_CR1_ENGC = 1; // Enable the general call address. I2C_OARH_ADDMODE = 0; // 7 bit address mode. I2C_OARH_ADDCONF = 1; // Docs say this must always be 1. // // Setup the bus characteristics. // I2C_CR2_ACK = 1; I2C_TRISER = 17; // // Turn on the interrupts. // I2C_ITR_ITBUFEN = 1; // Buffer interrupt enabled. I2C_ITR_ITEVTEN = 1; // Event interrupt enabled. I2C_ITR_ITERREN = 1; // // Configuration complete so turn the peripheral on. // I2C_CR1_PE = 1;}int main(){ __disable_interrupt(); InitialiseSystemClock(); InitialiseI2C(); __enable_interrupt(); while (1) { __wait_for_interrupt(); }}Can anyone see where I'm going wrong?Regards,Markl