summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Nazaryev <sergey@nazaryev.ru>2017-02-14 16:25:22 +0000
committerSergey Nazaryev <sergey@nazaryev.ru>2017-02-26 18:22:51 +0000
commit89b88288aec4657c3cc65200e3060a91d4e33281 (patch)
tree2b73db4e498daa9a1df8ac6916ab423933e4abd7
downloadvkr-mesh-master.zip
vkr-mesh-master.tar.gz
vkr-mesh-master.tar.bz2
Initial commitHEADmaster
-rw-r--r--.gitignore7
-rw-r--r--Makefile13
-rw-r--r--client/Makefile29
-rw-r--r--client/client.c25
-rw-r--r--nrf24l01.h160
-rw-r--r--server/Makefile29
-rw-r--r--server/server.c18
-rw-r--r--spi.c39
-rw-r--r--spi.h27
9 files changed, 347 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..47bd8f1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+client/nrf24l01-client
+server/nrf24l01-server
+*/*.hex
+*/*.o
+*.o
+*.swp
+*/*.swp
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..814a1dd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,13 @@
+all: server client
+
+server:
+ $(MAKE) -C server
+
+client:
+ $(MAKE) -C client
+
+clean:
+ $(MAKE) -C server clean
+ $(MAKE) -C client clean
+
+.PHONY: server client all clean
diff --git a/client/Makefile b/client/Makefile
new file mode 100644
index 0000000..4b6afb2
--- /dev/null
+++ b/client/Makefile
@@ -0,0 +1,29 @@
+PROGRAM = nrf24l01-client
+
+SRC = client.c ../spi.c
+OBJ = $(SRC:.c=.o)
+
+CFLAGS ?= -Wall -Wpedantic -Werror -I../ -mmcu=atmega328p
+LDFLAGS ?= -mmcu=atmega328p
+
+CROSS_COMPILE ?= avr-
+CC = $(CROSS_COMPILE)gcc
+
+all: $(PROGRAM).hex
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $< -Os -o$@
+
+$(PROGRAM): $(OBJ)
+ $(CC) $(LDFLAGS) $^ -Os -o$@
+
+$(PROGRAM).hex: $(PROGRAM)
+ $(CROSS_COMPILE)objcopy -j .text -j .data -O ihex $< $@
+
+deploy: $(PROGRAM).hex
+ avrdude -c usbasp -p m328p -U flash:w:$<:i
+
+clean:
+ rm -f $(OBJ) $(PROGRAM) $(PROGRAM).hex
+
+.PHONY: all clean deploy
diff --git a/client/client.c b/client/client.c
new file mode 100644
index 0000000..a6d51bd
--- /dev/null
+++ b/client/client.c
@@ -0,0 +1,25 @@
+#define F_CPU 1000000UL
+
+#include <util/delay.h>
+#include <nrf24l01.h>
+
+int main(void)
+{
+ uint8_t status;
+
+ nrf24l01_init();
+ nrf24l01_power_up();
+ nrf24l01_receive_mode();
+
+ while(1) {
+ if(is_data_received()) {
+ nrf24l01_receive_byte();
+
+ status = nrf24l01_read_reg(NRF24L01_REG_STATUS);
+ nrf24l01_write_reg(NRF24L01_REG_STATUS, status);
+ }
+ _delay_us(100000);
+ }
+
+ return 0;
+}
diff --git a/nrf24l01.h b/nrf24l01.h
new file mode 100644
index 0000000..95d3f48
--- /dev/null
+++ b/nrf24l01.h
@@ -0,0 +1,160 @@
+#ifndef __NRF24L01__H
+#define __NRF24L01__H
+
+#include <unistd.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#include "spi.h"
+
+#define PORT_NRF24L01 PORTB
+#define DDR_NRF24L01 DDRB
+#define DD_CE DDB1
+#define DD_IRQ DDB0
+
+#define NRF24L01_CMD_R_REGISTER 0x00
+#define NRF24L01_CMD_W_REGISTER 0x20
+#define NRF24L01_CMD_R_RX_PAYLOAD 0x61
+#define NRF24L01_CMD_W_TX_PAYLOAD 0xA0
+#define NRF24L01_CMD_NOP 0xFF
+#define NRF24L01_CMD_FLUSH_TX 0xE1
+
+#define NRF24L01_REG_STATUS 0x07
+#define NRF24L01_REG_STATUS_RX_DR 0x06
+#define NRF24L01_REG_STATUS_TX_DS 0x05
+#define NRF24L01_REG_STATUS_MAX_RT 0x04
+#define NRF24L01_REG_RX_PW_P0 0x11
+#define NRF24L01_REG_EN_AA 0x01
+#define NRF24L01_REG_SETUP_RETR 0x04
+#define NRF24L01_REG_CONFIG 0x00
+#define NRF24L01_REG_CONFIG_EN_CRC 0x3
+#define NRF24L01_REG_CONFIG_PWR_UP 0x1
+#define NRF24L01_REG_CONFIG_PRIM_RX 0x0
+
+#define MAX_PAYLOAD_IN_BYTES 1
+
+static inline void nrf24l01_ce_high()
+{
+ PORT_NRF24L01 |= _BV(DD_CE);
+}
+
+static inline void nrf24l01_ce_low()
+{
+ PORT_NRF24L01 &= ~_BV(DD_CE);
+}
+
+static inline uint8_t nrf24l01_read_cmd(uint8_t cmd)
+{
+ return spi_two_byte(cmd, NRF24L01_CMD_NOP);
+}
+
+static inline uint8_t nrf24l01_read_reg(uint8_t reg)
+{
+ return nrf24l01_read_cmd(NRF24L01_CMD_R_REGISTER | reg);
+}
+
+static inline void nrf24l01_write_cmd(uint8_t cmd, uint8_t data)
+{
+ spi_two_byte(cmd, data);
+}
+
+static inline void nrf24l01_write_reg(uint8_t reg, uint8_t data)
+{
+ nrf24l01_write_cmd(NRF24L01_CMD_W_REGISTER | reg, data);
+}
+
+static inline void nrf24l01_power_up()
+{
+ uint8_t config = nrf24l01_read_reg(NRF24L01_REG_CONFIG);
+ nrf24l01_write_reg(NRF24L01_REG_CONFIG, config | _BV(NRF24L01_REG_CONFIG_PWR_UP));
+ _delay_us(10);
+}
+
+static inline void nrf24l01_power_down()
+{
+ uint8_t config = nrf24l01_read_reg(NRF24L01_REG_CONFIG);
+ nrf24l01_write_reg(NRF24L01_REG_CONFIG, config & ~_BV(NRF24L01_REG_CONFIG_PWR_UP));
+}
+
+static inline void nrf24l01_init()
+{
+ spi_init();
+
+ //nrf24l01_write_reg(NRF24L01_REG_SETUP_RETR, 0x00);
+ //nrf24l01_write_reg(NRF24L01_REG_EN_AA, 0x00);
+ nrf24l01_write_reg(NRF24L01_REG_RX_PW_P0, MAX_PAYLOAD_IN_BYTES);
+ nrf24l01_ce_low();
+}
+
+static inline void nrf24l01_receive_mode()
+{
+ uint8_t config = nrf24l01_read_reg(NRF24L01_REG_CONFIG);
+ nrf24l01_write_reg(NRF24L01_REG_CONFIG, config | _BV(NRF24L01_REG_CONFIG_PRIM_RX));
+ nrf24l01_ce_high();
+ _delay_us(200);
+}
+
+static inline void nrf24l01_transmit_mode()
+{
+ uint8_t config = nrf24l01_read_reg(NRF24L01_REG_CONFIG);
+ config &= ~_BV(NRF24L01_REG_CONFIG_PRIM_RX);
+
+ nrf24l01_ce_low();
+ nrf24l01_write_reg(NRF24L01_REG_CONFIG, config);
+ nrf24l01_ce_high();
+ _delay_us(15);
+ nrf24l01_ce_low();
+ _delay_us(200);
+}
+
+static inline uint8_t is_data_received()
+{
+ uint8_t status = nrf24l01_read_reg(NRF24L01_REG_STATUS);
+ return status & _BV(NRF24L01_REG_STATUS_RX_DR);
+}
+
+static inline uint8_t nrf24l01_receive_byte()
+{
+ return nrf24l01_read_cmd(NRF24L01_CMD_R_RX_PAYLOAD);
+}
+
+static inline uint8_t is_data_transmitted(uint8_t status)
+{
+ return status & _BV(NRF24L01_REG_STATUS_TX_DS);
+}
+
+static inline uint8_t is_data_transmit_failed(uint8_t status)
+{
+ return status & _BV(NRF24L01_REG_STATUS_MAX_RT);
+}
+
+static inline int nrf24l01_send_byte(uint8_t data)
+{
+ nrf24l01_write_cmd(NRF24L01_CMD_W_TX_PAYLOAD, data);
+ nrf24l01_transmit_mode();
+
+ uint8_t status;
+ uint8_t err = 0;
+
+ while (1) {
+ status = nrf24l01_read_reg(NRF24L01_REG_STATUS);
+
+ if(is_data_transmitted(status)) {
+ nrf24l01_write_reg(NRF24L01_REG_STATUS, status);
+ break;
+ }
+
+ if(is_data_transmit_failed(status)) {
+ nrf24l01_write_cmd(NRF24L01_CMD_FLUSH_TX, NRF24L01_CMD_NOP);
+ err = 1;
+ break;
+ }
+
+ _delay_us(10000);
+ }
+
+ nrf24l01_write_reg(NRF24L01_REG_STATUS, status);
+ nrf24l01_receive_mode();
+ return err;
+}
+
+#endif // NRF24L01__H
diff --git a/server/Makefile b/server/Makefile
new file mode 100644
index 0000000..340f0be
--- /dev/null
+++ b/server/Makefile
@@ -0,0 +1,29 @@
+PROGRAM = nrf24l01-server
+
+SRC = server.c ../spi.c
+OBJ = $(SRC:.c=.o)
+
+CFLAGS ?= -Wall -Wpedantic -Werror -I../ -mmcu=atmega328p
+LDFLAGS ?= -mmcu=atmega328p
+
+CROSS_COMPILE ?= avr-
+CC = $(CROSS_COMPILE)gcc
+
+all: $(PROGRAM).hex
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $< -Os -o$@
+
+$(PROGRAM): $(OBJ)
+ $(CC) $(LDFLAGS) $^ -Os -o$@
+
+$(PROGRAM).hex: $(PROGRAM)
+ $(CROSS_COMPILE)objcopy -j .text -j .data -O ihex $< $@
+
+deploy: $(PROGRAM).hex
+ avrdude -c usbasp -p m328p -U flash:w:$<:i
+
+clean:
+ rm -f $(OBJ) $(PROGRAM) $(PROGRAM).hex
+
+.PHONY: all clean deploy
diff --git a/server/server.c b/server/server.c
new file mode 100644
index 0000000..6b85493
--- /dev/null
+++ b/server/server.c
@@ -0,0 +1,18 @@
+#define F_CPU 1000000UL
+
+#include <avr/io.h>
+#include <util/delay.h>
+#include <nrf24l01.h>
+
+int main(void)
+{
+ nrf24l01_init();
+ nrf24l01_power_up();
+
+ uint8_t data = 0;
+ while(1)
+ if(!nrf24l01_send_byte(data))
+ data++;
+
+ return 0;
+}
diff --git a/spi.c b/spi.c
new file mode 100644
index 0000000..623f5d1
--- /dev/null
+++ b/spi.c
@@ -0,0 +1,39 @@
+#include <stdint.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "spi.h"
+
+void spi_init()
+{
+ DDR_SPI &= ~((1<<DD_MOSI)|(1<<DD_MISO)|(1<<DD_SS)|(1<<DD_SCK));
+ DDR_SPI |= ((1<<DD_MOSI)|(1<<DD_SS)|(1<<DD_SCK));
+
+ SPCR = ((1<<SPE)| // SPI Enable
+ (0<<SPIE)| // SPI Interupt Enable
+ (0<<DORD)| // Data Order (0:MSB first / 1:LSB first)
+ (1<<MSTR)| // Master/Slave select
+ (1<<SPR1)|(1<<SPR0)| // SPI Clock Rate
+ (0<<CPOL)| // Clock Polarity (0:SCK low / 1:SCK hi when idle)
+ (0<<CPHA)); // Clock Phase (0:leading / 1:trailing edge sampling)
+
+ SPSR = (0<<SPIF)|(0<<WCOL)|(0<<SPI2X); // Double Clock Rate
+}
+
+uint8_t spi_fast_shift(uint8_t data)
+{
+ SPDR = data;
+ while((SPSR & (1<<SPIF))==0);
+ return SPDR;
+}
+
+uint8_t spi_two_byte(uint8_t cmd, uint8_t arg)
+{
+ uint8_t data_buf;
+
+ spi_cs_low();
+ spi_fast_shift(cmd);
+ data_buf = spi_fast_shift(arg);
+ spi_cs_high();
+
+ return data_buf;
+}
diff --git a/spi.h b/spi.h
new file mode 100644
index 0000000..51351a5
--- /dev/null
+++ b/spi.h
@@ -0,0 +1,27 @@
+#ifndef _SPI_H_
+#define _SPI_H_
+
+#include <stdint.h>
+#include <avr/io.h>
+
+#define PORT_SPI PORTB
+#define DDR_SPI DDRB
+#define DD_MISO DDB4
+#define DD_MOSI DDB3
+#define DD_SS DDB2
+#define DD_SCK DDB5
+
+inline void spi_cs_low()
+{
+ PORT_SPI &= ~(_BV(DD_SS));
+}
+
+inline void spi_cs_high()
+{
+ PORT_SPI |= _BV(DD_SS);
+}
+
+extern void spi_init();
+extern uint8_t spi_two_byte(uint8_t cmd, uint8_t data);
+
+#endif /* _SPI_H_ */