Witam,
szukałem, próbowałem ale nie jestem w stanie skomunikować się ATMega8 i CC1000PP.
Piszę w C. Zmontowałem płytkę (trawiona), napisałem kod (przerobiłem trochę dostępne sample) ale nie działa.
Oczywiście nie chodzi mi zaraz o nadawanie/odbieranie, bo to oczywiście nie działa.
Póki co chciałem skonfigurować CC1000. Staram się więc na próbę zapisać coś do jego rejestrów konfiguracyjnych i odczytać z nich te właśnie wartości wyświetlając na diodach (PORTD).
Oczywiście czytam same 0.
Zwracam się więc do kolegów z prośbą o przejrzenie kodu i pomoc.
Gdzie tkwi błąd? A może to hardware?
Garść info:
- konwerter napięć Mega8-CC1000PP na układach 74LV125 i 74HCT126 jak w projekcie
Link
- Mega8 z kwarcem 11.0592MHz (fuse bits na 95% dobrze zrobione)
- CC1000 zasilany +3.3V, Mega8 +5V
W kodzie zostawiłem większość funkcji ale najważniejsze to WriteToCC1000Register oraz ReadFromCC1000Register, bo tylko je w zasadzie w main używam i to one nie działają.
#include <avr/io.h>
#include <avr/wdt.h> // macros for AVR watchdog timer
#include <util/delay.h>
#include <avr/interrupt.h>
//definition of CC1000 registers
#define CC1000_MAIN 0x00
#define CC1000_FREQ_2A 0x01
#define CC1000_FREQ_1A 0x02
#define CC1000_FREQ_0A 0x03
#define CC1000_FREQ_2B 0x04
#define CC1000_FREQ_1B 0x05
#define CC1000_FREQ_0B 0x06
#define CC1000_FSEP1 0x07
#define CC1000_FSEP0 0x08
#define CC1000_CURRENT 0x09
#define CC1000_FRONT_END 0x0A
#define CC1000_PA_POW 0x0B
#define CC1000_PLL 0x0C
#define CC1000_LOCK 0x0D
#define CC1000_CAL 0x0E
#define CC1000_MODEM2 0x0F
#define CC1000_MODEM1 0x10
#define CC1000_MODEM0 0x11
#define CC1000_MATCH 0x12
#define CC1000_FSCTRL 0x13
#define CC1000_FSHAPE7 0x14
#define CC1000_FSHAPE6 0x15
#define CC1000_FSHAPE5 0x16
#define CC1000_FSHAPE4 0x17
#define CC1000_FSHAPE3 0x18
#define CC1000_FSHAPE2 0x19
#define CC1000_FSHAPE1 0x1A
#define CC1000_FSDELAY 0x1B
#define CC1000_PRESCALER 0x1C
#define CC1000_TEST6 0x40
#define CC1000_TEST5 0x41
#define CC1000_TEST4 0x42
#define CC1000_TEST3 0x43
#define CC1000_TEST2 0x44
#define CC1000_TEST1 0x45
#define CC1000_TEST0 0x46
//definition of pins used to communicate with CC1000
#define PDATA 4
#define PDATA_PORT PORTB
#define PDATA_PIN PINB
#define PDATA_DDR DDRB
#define PCLK 3
#define PCLK_PORT PORTB
#define PALE 5
#define PALE_PORT PORTB
#define DIO 0
#define DIO_PORT PORTB
#define DIO_PIN PINB
#define DIO_DDR DDRB
#define DCLK 2
#define DCLK_PIN PINB
//This pin sets the direction of an external level conventer,
// H means FROM CC1000, L means to CC1000
#define DDRCC 1
#define DDRCC_PORT PORTB
//Copied from SmartRF Studio
#define TX_CURRENT 0x81
#define RX_CURRENT 0x44
#define TX_PLL 0x48
#define RX_PLL 0x58
#define OUTPUT_POWER 0xff
const char registers[] = {0x51, 0x50, 0xA0, 0x00, 0x41, 0xF6, // 00 - 05
0x10, 0x02, 0x80, 0x44, 0x12, // 06 - 0A
0x0F, 0x58, 0x10, 0x26, 0x9C, // 0B - 0F
0x6F, 0x55, 0x70, 0x01, 0x00, // 10 - 14
0x10, 0x08, 0x3F, 0x04, 0x00, // 15 - 19
0x00, 0x00 }; // 1A - 1B
volatile char RxBuff[2]; //Receive buffer
volatile char RxW; //Write "pointer" for receive buffer
volatile char RxR; //Read "pointer" for receive buffer
volatile char TxBuff[2]; //Transmit buffer
volatile char TxW; //Write "pointer" for transmit buffer
volatile char TxR; //Read "pointer" for transmit buffer
void writeToRxBuffer(char Data) {
RxW++; //Move pointer to the next location
if(RxW>=30) RxW=0; //If behind buffer set it to 0
if(RxW==RxR) { //If read and write pointers are equal
//buffer overrun
//move pointer back
if(RxW==0) {
RxW=29;
} else {
RxW--;
}
} else {
RxBuff[(int)RxW]=Data; //Write data to buffer
}
}
char readFromRxBuffer(void) {
RxR++; //Move pointer to the next location
if(RxR>=30) RxR=0; //If behind buffer set it to 0
return RxBuff[(int)RxR]; //Read from buffer
}
//Almost the same functions as above but for TxBuffer
void writeToTxBuffer(char Data) {
TxW++;
if(TxW>=30) TxW=0;
if(TxW==TxR) {
//buffer overrun
//move pointer back
if(TxW==0) {
TxW=29;
} else {
TxW--;
}
} else {
TxBuff[(int)TxW]=Data;
}
}
char readFromTxBuffer(void) {
TxR++;
if(TxR>=30) TxR=0;
return TxBuff[(int)TxR];
}
//sets the direction of MCU pins and external level conventer
char setIO(char isinput) {
char res=0; //stores result (last state)
//examine the external level conventer direction pin
if(DDRCC_PORT & (1<<DDRCC)) res=1;
if(isinput) { //set MCU as input
DIO_DDR&=~(1<<DIO); //set pin direction
PDATA_DDR&=~(1<<PDATA); //set pin direction
DDRCC_PORT|=(1<<DDRCC); //set external level conventer pin
DIO_PORT&=~(1<<DIO); //disconnect pull-up resistor
PDATA_PORT&=~(1<<PDATA); //disconnect pull-up resistor
}
else { //set MCU as output
// change state of MCU pins to the state of CC1000 pins
// to avoid higher current flow
//if port level is different than level sensed at the same pin...
if((DIO_PORT&(1<<DIO))!=(DIO_PIN&(1<<DIO)))
//change the state of the pin, so they were equal
DIO_PORT^=1<<DIO;
//the same for PDATA
if((PDATA_PORT&(1<<PDATA))!=(PDATA_PIN&(1<<PDATA)))
PDATA_PORT^=1<<PDATA;
DDRCC_PORT&=~(1<<DDRCC); //set external level conventer pin
DIO_DDR|=(1<<DIO); //set pin as output
PDATA_DDR|=(1<<PDATA); //set pin as output
}
return res; //return old value
}
void CC1000PP_send(char bit) {
if(bit) {
DIO_PORT|=(1<<DIO); //DIO=1;
} else {
DIO_PORT&=~(1<<DIO); //DIO=0;
}
while((DCLK_PIN & (1<<DCLK))==0); //wait for clock high state
while((DCLK_PIN & (1<<DCLK))!=0); //wait for clock low state
}
void CC1000PP_send_byte(char my_byte) {
char my_bit=1; //my_bit=00000001b
while(1) {
CC1000PP_send(my_byte & my_bit);
if(my_bit==128) break; //if(my_bit=10000000b) break;
my_bit <<= 1; //00000001 -> 00000010 -> ... -> 10000000
}
}
char CC1000PP_receive(void) {
char ret;
while((DCLK_PIN & (1<<DCLK))==0); //wait for clock high state
ret = DIO_PIN & (1<<DIO); //sample the pin state
while((DCLK_PIN & (1<<DCLK))!=0); //wait for clock low state
return ret;
}
char CC1000PP_receive_byte(void) {
char my_bit=1, my_byte=0; //my_byte is used for storing result
while(1) {
if(CC1000PP_receive()) my_byte|=my_bit;
if(my_bit==128) break;
my_bit <<= 1;
}
return my_byte;
}
//write bit to the configuration register of CC1000
void CC1000PP_config_write_bit(char val) {
PCLK_PORT|=(1<<PCLK); //PCLK=1
if(val==0) {
PDATA_PORT&=~(1<<PDATA); //PDATA=0
} else {
PDATA_PORT|=(1<<PDATA); //PDATA=1
}
PCLK_PORT&=~(1<<PCLK); //PCLK=0
}
void WriteToCC1000Register(char address, char data) {
char BitCounter,oldIO; // this is to ensure the falling edge on PALE
PALE_PORT|=(1<<PALE); //PALE=1
PALE_PORT&=~(1<<PALE); // PALE=0
oldIO=setIO(0); //set MCU as output
// Send address bits
for(BitCounter=0;BitCounter<7;BitCounter++) {
//MSB first (address is 7 bit long)
CC1000PP_config_write_bit(address&0x40);
address=address<<1;
}
// Send read/write bit (1)
CC1000PP_config_write_bit(1);
// Send data bits
PCLK_PORT|=(1<<PCLK); //PCLK=1
PALE_PORT|=(1<<PALE); //PALE=1
for(BitCounter=0;BitCounter<8;BitCounter++) {
CC1000PP_config_write_bit(data&0x80);
data=data<<1;
}
PCLK_PORT|=(1<<PCLK); //PCLK=1
setIO(oldIO); //restore previous setting
}
char ReadFromCC1000Register(char address) {
char data, BitCounter, oldIO;
oldIO = setIO(0); //set MCU as output
//this is to ensure the falling edge on PALE
PALE_PORT|=(1<<PALE); //PALE=1
PALE_PORT&=~(1<<PALE); //PALE=0
for(BitCounter=0;BitCounter<7;BitCounter++) {
CC1000PP_config_write_bit(address&0x40); //Send MSB first
address=address<<1;
}
// Send read/write bit (0)
CC1000PP_config_write_bit(0);
// Receive data bits
PCLK_PORT|=(1<<PCLK); //PCLK=1
PALE_PORT|=(1<<PALE); //PALE=1
PDATA_PORT|=(1<<PDATA); //PDATA=1
setIO(1); //set MCU as input
data=0;
for(BitCounter=0;BitCounter<8;BitCounter++) {
PCLK_PORT&=~(1<<PCLK); //PCLK=0
data=data<<1;
if((PDATA_PIN&(1<<PDATA))!=0) data|=0x01;
PCLK_PORT|=(1<<PCLK); //PCLK=1
}
setIO(oldIO); //restore old direction
return data;
}
int main(void) {
char blink=0x3A;
TxW=TxR=RxW=RxR=0;
MCUCSR=0;
DDRB=(1<<PALE)|(1<<PCLK)|(1<<DDRCC);
// PALE,PCLK,DDRCC-wy DCLK-we
DDRB&=~(1<<DCLK);
DDRC=0xff;
DDRD=0xff;
PORTC=0x00;
PALE_PORT|=(1<<PALE); //PALE=1
//reset CC1000:
WriteToCC1000Register(CC1000_MAIN, blink); //reset start, 0011 1010 xtal core on
blink=0x3B;
WriteToCC1000Register(CC1000_MAIN, blink); //reset end, 0011 1011 xtal core on
_delay_ms(2);
// zapis wartości do rejestrów:
int i;
for(i=1; i<28; i++) //write all registers
WriteToCC1000Register(i,registers[(int)i]);
//jakiś świecenie, by wiedzieć że układ żyje
PORTD=~blink;
_delay_ms(300);
PORTD=blink;
_delay_ms(300);
PORTD=~blink;
_delay_ms(300);
PORTD=blink;
//odczyt z tych samych rejestrów co zapisaliśmy
for(i=1; i<28; i++) {
PORTD = ReadFromCC1000Register(i);
_delay_ms(500);
}
//pętla kończąca odczyt
while(1) {
PORTD = 0xAA;
_delay_ms(500);
PORTD = 0x55;
_delay_ms(500);
}
}
No i między zaprogramowanym świeceniem na porcie D mam same zera (tam gdzie powinien coś odczytać).
Proszę o pomoc, bo nie widzę siebie rozwiązującego ten problem
Pozdrawiam...