diff options
| -rw-r--r-- | Recv.Makefile (renamed from Makefile) | 2 | ||||
| -rw-r--r-- | Send.Makefile | 44 | ||||
| -rw-r--r-- | nrfm.c | 127 | ||||
| -rw-r--r-- | nrfm.h | 9 | ||||
| -rw-r--r-- | recv.c | 53 | ||||
| -rw-r--r-- | send.c (renamed from main.c) | 0 |
6 files changed, 205 insertions, 30 deletions
@@ -2,7 +2,7 @@ CC = avr-gcc MCU = atmega328p TARGET = app -SRC = main.c uart.c nrfm.c +SRC = recv.c uart.c nrfm.c OBJ = $(SRC:.c=.o) CFLAGS = -std=gnu99 diff --git a/Send.Makefile b/Send.Makefile new file mode 100644 index 0000000..7c20759 --- /dev/null +++ b/Send.Makefile @@ -0,0 +1,44 @@ +CC = avr-gcc +MCU = atmega328p +TARGET = app + +SRC = send.c uart.c nrfm.c +OBJ = $(SRC:.c=.o) + +CFLAGS = -std=gnu99 +CFLAGS += -Os +CFLAGS += -Wall +CFLAGS += -mmcu=$(MCU) +CFLAGS += -DBAUD=115200 +CFLAGS += -DF_CPU=16000000UL +CFLAGS += -ffunction-sections -fdata-sections + +LDFLAGS = -mmcu=$(MCU) +LDFLAGS += -Wl,--gc-sections + +HEX_FLAGS = -O ihex +HEX_FLAGS += -j .text -j .data + +AVRDUDE_FLAGS = -p $(MCU) +AVRDUDE_FLAGS += -c arduino +AVRDUDE_FLAGS += -P /dev/cuaU0 +AVRDUDE_FLAGS += -D -U + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +elf: $(OBJ) + $(CC) $(LDFLAGS) $(OBJ) -o $(TARGET).elf + +hex: elf + avr-objcopy $(HEX_FLAGS) $(TARGET).elf $(TARGET).hex + +upload: hex + avrdude $(AVRDUDE_FLAGS) flash:w:$(TARGET).hex:i + +.PHONY: clean + +clean: + rm *.o *.elf *.hex + + @@ -19,15 +19,6 @@ #define NRF_CE_DDR DDRB #define NRF_CE_PORT PORTB -#define NRF_IRQ PD7 -#define NRF_IRQ_DDR DDRD -#define NRF_IRQ_PORT PORTD -#define NRF_IRQ_PCIE PCIE2 -#define NRF_IRQ_PCIR PCICR -#define NRF_IRQ_PCINT PCINT23 -#define NRF_IRQ_PCMSK PCMSK2 -#define NRF_IRQ_PCINTVEC PCINT2_vect - #define NRF_NOP 0xFF #define NRF_R_REGISTER 0x1F #define NRF_W_REGISTER 0x20 @@ -37,7 +28,6 @@ #define NRF_MODCHG_DELAY_MS 5 -#define MAXPDLEN 32 #define LEN(a) (sizeof(a) / sizeof(a[0])) const char *bittab[16] = { @@ -114,7 +104,7 @@ static inline void reset_irqs(void) write_reg(0x07, 0b01111110); } -static inline void enable_tx(void) +static inline void tx_mode(void) { uint8_t rv; @@ -127,7 +117,31 @@ static inline void enable_tx(void) } } -static inline void flush_tx_fifo(void) +static inline void rx_mode(void) +{ + uint8_t rv; + + rv = read_reg(0x00); + if ((rv & 0x03) != 0x02) { + rv |= (1 << NRF_PWR_UP); + rv |= (1 << NRF_PRIM_RX); + write_reg(0x00, rv); + _delay_ms(NRF_MODCHG_DELAY_MS); + } +} + +static inline void enable_chip(void) +{ + NRF_CE_PORT |= (1 << NRF_CE); + _delay_us(130); +} + +static inline void disable_chip(void) +{ + NRF_CE_PORT &= ~(1 << NRF_CE); +} + +static inline void flush_tx(void) { SPI_PORT &= ~(1 << SPI_SS); SPDR = 0b11100001; @@ -136,6 +150,25 @@ static inline void flush_tx_fifo(void) SPI_PORT |= (1 << SPI_SS); } +static inline void flush_rx(void) +{ + SPI_PORT &= ~(1 << SPI_SS); + SPDR = 0b11100010; + while (!(SPSR & (1 << SPIF))) + ; + SPI_PORT |= (1 << SPI_SS); +} + +static inline uint8_t rx_pdlen(void) +{ + SPI_PORT &= ~(1 << SPI_SS); + SPDR = 0b01100000; + while (!(SPSR & (1 << SPIF))) + ; + SPI_PORT |= (1 << SPI_SS); + return SPDR; +} + void radio_print_config(void) { char s[22]; @@ -169,11 +202,6 @@ void radio_init(const uint8_t rxaddr[ADDRLEN]) NRF_CE_DDR |= (1 << NRF_CE); NRF_CE_PORT &= ~(1 << NRF_CE); - NRF_IRQ_DDR &= ~(1 << NRF_IRQ); - NRF_IRQ_PORT &= ~(1 << NRF_IRQ); - NRF_IRQ_PCIR |= (1 << NRF_IRQ_PCIE); - NRF_IRQ_PCMSK |= (1 << NRF_IRQ_PCINT); - _delay_ms(110); /* power on reset delay */ write_reg(0x00, 0b00111100); /* use 2-byte CRC, enable only the rx interrupt */ @@ -190,40 +218,41 @@ void radio_init(const uint8_t rxaddr[ADDRLEN]) setaddr(0x0A, rxaddr); } -void radio_sendto(const uint8_t addr[ADDRLEN], const void *msg, uint8_t n) +void radio_sendto(const uint8_t addr[ADDRLEN], const char *msg, uint8_t n) { uint8_t cfg; - uint8_t i, j, j0, jmax; + uint8_t i, j, jmax; uint8_t rv, maxrt, txds; + disable_chip(); + cfg = read_reg(0x00); - enable_tx(); + tx_mode(); reset_irqs(); - flush_tx_fifo(); + flush_tx(); setaddr(0x10, addr); setaddr(0x0A, addr); - txds = 0, maxrt = 0, jmax = n - 1; - for (i = 0; i < n; i += MAXPDLEN) { SPI_PORT &= ~(1 << SPI_SS); SPDR = 0b10100000; while (!(SPSR & (1 << SPIF))) ; - j0 = i + MAXPDLEN - 1; - for (j = j0 < jmax ? j0 : jmax; j >= i; j--) { - SPDR = ((uint8_t *)msg)[j]; + jmax = i + MAXPDLEN; + for (j = i; j < jmax; j++) { + SPDR = msg[j]; while (!(SPSR & (1 << SPIF))) ; } SPI_PORT |= (1 << SPI_SS); - NRF_CE_PORT |= (1 << NRF_CE); + enable_chip(); _delay_us(12); - NRF_CE_PORT &= ~(1 << NRF_CE); + disable_chip(); + txds = 0, maxrt = 0; do { rv = read_reg(0x07); txds = rv & (1 << 5); @@ -242,3 +271,45 @@ void radio_sendto(const uint8_t addr[ADDRLEN], const void *msg, uint8_t n) _delay_ms(NRF_MODCHG_DELAY_MS); } +void radio_listen(void) +{ + rx_mode(); + enable_chip(); +} + +uint8_t radio_recv(char *buf, uint8_t n) +{ + uint8_t rv, readlen, pdlen, maxlen; + + readlen = 0; + disable_chip(); + + rv = read_reg(0x07); + if (rv & ~(1 << 6)) { + pdlen = rx_pdlen(); + maxlen = pdlen < n ? pdlen : n; + + if (pdlen <= MAXPDLEN) { + SPI_PORT &= ~(1 << SPI_SS); + SPDR = 0b01100001; + while (!(SPSR & (1 << SPIF))) + ; + for (readlen = 0; readlen < maxlen; readlen++) { + SPDR = NRF_NOP; + while (!(SPSR & (1 << SPIF))) + ; + buf[readlen] = SPDR; + } + SPI_PORT |= (1 << SPI_SS); + if (pdlen != n) + flush_rx(); + } else { + flush_rx(); + readlen = 0; + } + + reset_irqs(); + } + + return readlen; +} @@ -4,9 +4,16 @@ #include <stdint.h> #define ADDRLEN 5 +#define MAXPDLEN 32 void radio_init(const uint8_t rxaddr[ADDRLEN]); + void radio_print_config(void); -void radio_sendto(const uint8_t addr[ADDRLEN], const void *msg, uint8_t n); + +void radio_listen(void); + +uint8_t radio_recv(char *buf, uint8_t n); + +void radio_sendto(const uint8_t addr[ADDRLEN], const char *msg, uint8_t n); #endif /* NRFM_H */ @@ -0,0 +1,53 @@ +#include <stdint.h> +#include <string.h> +#include <avr/interrupt.h> + +#include "nrfm.h" +#include "uart.h" + +#define RX_PIN PD7 +#define RX_DDR DDRD +#define RX_PORT PORTD +#define RX_PCIE PCIE2 +#define RX_PCINT PCINT23 +#define RX_PCMSK PCMSK2 +#define RX_PCINTVEC PCINT2_vect + +int main(void) +{ + uint8_t rxaddr[] = { 194, 178, 83 }; + + RX_DDR &= ~(1 << RX_PIN); + RX_PORT &= ~(1 << RX_PIN); + PCICR |= (1 << RX_PCIE); + RX_PCMSK |= (1 << RX_PCINT); + + uart_init(); + radio_init(rxaddr); + radio_print_config(); + + sei(); + radio_listen(); + + for (;;) + ; + + return 0; +} + +ISR(RX_PCINTVEC) +{ + uint8_t n; + char buf[MAXPDLEN + 1]; + + cli(); + + uart_write_line("DEBUG: Pin change IRQ"); + + n = radio_recv(buf, MAXPDLEN); + buf[n] = '\0'; + uart_write("INFO: "); + uart_write_line(buf); + + sei(); +} |
