Mam problem z napisaniem programu do obsługi i2c w trybie slave w w/w klocku.
Chciałbym aby slave odpowiadał conajmniej czterema bajtami danych, niestety korzytajac z tego co już mam nie moge wysyłać więcej niż 2 bajty ze slave do mastera ponieważ klocek przestaje odpowiadać. Aby wysyłać wiekszą ilość danych dopisywałem kolejne funkcje I2C_SendData(); jeden pod drugim.
Jak narazie udało mi się zrobić tak, że wysyłam z mastera do stm8s adres urządzenia (w moim przypadku 0x20) a stm8s odpowiada mi jednym bajtem danych (narazie na sztywno ustawiony). Z tego co sie zorientowałem program mam na bank zły, oscyloskop podpięty pod linie danych pokazuje w jednym cyklu 3 bajty (???) ... no ale działa poprawnie
i jakieś "podłoże" programu jest.
Funkcja GPIO_WriteReverse(GPIOD, GPIO_PIN_0); służy do informowania kiedy wykonuje się pętla (na pinie D0 jest dioda led) i powinna zmieniać stan za każdym razem jak wykona się transfer danych... i niewiedzieć dlaczego przy pojedyńczej transmisji dioda zmienia stan dwa razy, z tego wynika że pętla wykonuje się dwa razy (???) (to jest przypadek kiedy otrzymuje w/w jeden lub dwa bajty dane od slave'a, w przypadku wiekszej ilości bajtów albo raz zmieni stan albo nic sie nie dzieje - i oczywiscie klocek zatrzymuje się)
korzystałem z tego Link i tego Link (plik main_slave_10bit.c) dodam że próbowałem już różnych wariancji z funkcją I2C_ClearFlag() i I2C_CheckEvent() ale za każdym razem było to samo.
p.s. jak by sie kto pytał to urządzeniem master i2c jest Lego NXT intelligent brick
//EDIT
Dobra udało mi sie samemu dojść do tego jak to zrobić, pomiędzy kolejne SendData trzeba było powstawiać funkcje które zaczeka aż zakończy sie wysyłanie poprzedniego bajtu i zresetuje flagi. Tylko dalej nie moge dojść do tego dlaczego w pojedynczym cyklu komunikacji dwa razy wykonuje sie ta petla. Co do "bezpańskiego" bajtu który mi sie pojawiał to widocznie tak ma być, bo z innymi peryferiami na i2c też tak sie dzieje (żyroskop z Wii Motion Plus), widocznie Lego NXT jest rodzaju t.t.t.m. (ten typ tak ma).
Kod dla potomnych:
Chciałbym aby slave odpowiadał conajmniej czterema bajtami danych, niestety korzytajac z tego co już mam nie moge wysyłać więcej niż 2 bajty ze slave do mastera ponieważ klocek przestaje odpowiadać. Aby wysyłać wiekszą ilość danych dopisywałem kolejne funkcje I2C_SendData(); jeden pod drugim.
Jak narazie udało mi się zrobić tak, że wysyłam z mastera do stm8s adres urządzenia (w moim przypadku 0x20) a stm8s odpowiada mi jednym bajtem danych (narazie na sztywno ustawiony). Z tego co sie zorientowałem program mam na bank zły, oscyloskop podpięty pod linie danych pokazuje w jednym cyklu 3 bajty (???) ... no ale działa poprawnie
Funkcja GPIO_WriteReverse(GPIOD, GPIO_PIN_0); służy do informowania kiedy wykonuje się pętla (na pinie D0 jest dioda led) i powinna zmieniać stan za każdym razem jak wykona się transfer danych... i niewiedzieć dlaczego przy pojedyńczej transmisji dioda zmienia stan dwa razy, z tego wynika że pętla wykonuje się dwa razy (???) (to jest przypadek kiedy otrzymuje w/w jeden lub dwa bajty dane od slave'a, w przypadku wiekszej ilości bajtów albo raz zmieni stan albo nic sie nie dzieje - i oczywiscie klocek zatrzymuje się)
korzystałem z tego Link i tego Link (plik main_slave_10bit.c) dodam że próbowałem już różnych wariancji z funkcją I2C_ClearFlag() i I2C_CheckEvent() ale za każdym razem było to samo.
void main(void)
{
GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST);
I2C_Cmd(ENABLE);
I2C_DeInit();
/* Initialize the I2C peripheral */
I2C_Init(100000, 0x20, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);
while(1)
{
/* Test on EV1 and clear it */
while(!I2C_CheckEvent(I2C_EVENT_SLAVE_ADDRESS_MATCHED));
{
I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
}
I2C_SendData(0xAB);
//I2C_SendData(0xAC);
//I2C_SendData(0xAD); //kolejne bajty danych
GPIO_WriteReverse(GPIOD, GPIO_PIN_0); //dioda led
}
}
p.s. jak by sie kto pytał to urządzeniem master i2c jest Lego NXT intelligent brick
//EDIT
Dobra udało mi sie samemu dojść do tego jak to zrobić, pomiędzy kolejne SendData trzeba było powstawiać funkcje które zaczeka aż zakończy sie wysyłanie poprzedniego bajtu i zresetuje flagi. Tylko dalej nie moge dojść do tego dlaczego w pojedynczym cyklu komunikacji dwa razy wykonuje sie ta petla. Co do "bezpańskiego" bajtu który mi sie pojawiał to widocznie tak ma być, bo z innymi peryferiami na i2c też tak sie dzieje (żyroskop z Wii Motion Plus), widocznie Lego NXT jest rodzaju t.t.t.m. (ten typ tak ma).
Kod dla potomnych:
void main(void)
{
GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST);
I2C_Cmd(ENABLE);
I2C_DeInit();
/* Initialize the I2C peripheral */
I2C_Init(100000, 0x20, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);
u8 data[4] = {0xAB, 0xCD, 0xEF, 0x01};
int j;
while(1)
{
/* Test on EV1 and clear it */
while(!I2C_CheckEvent(I2C_EVENT_SLAVE_ADDRESS_MATCHED));
{
I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
}
for(j = 0; j <= 3; j++)
{
if(I2C_CheckEvent(I2C_EVENT_SLAVE_BYTE_TRANSMITTED))
{
if(I2C_CheckEvent(I2C_EVENT_SLAVE_ACK_FAILURE))
{
I2C_ClearFlag(I2C_FLAG_ACKNOWLEDGEFAILURE);
}
I2C_SendData(data[j]);
while (!I2C_CheckEvent(I2C_EVENT_SLAVE_BYTE_TRANSMITTED));
I2C_ClearFlag(I2C_FLAG_TRANSFERFINISHED);
}
}
GPIO_WriteReverse(GPIOD, GPIO_PIN_0); //dioda led
}
}