restore
This commit is contained in:
parent
5227e9c161
commit
74f17bf353
@ -1 +1 @@
|
||||
<AVRStudio><MANAGEMENT><ProjectName>Rmodule</ProjectName><Created>14-Nov-2013 11:48:57</Created><LastEdit>08-Dec-2013 20:52:55</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>14-Nov-2013 11:48:57</Created><Version>4</Version><Build>4, 19, 0, 730</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\Rmodule.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>C:\Hard\Git\Rmodule\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATmega8.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>C:\Hard\Git\Rmodule\nrf24l01\radioPinFunctions.c</SOURCEFILE><SOURCEFILE>C:\Hard\Git\Rmodule\nrf24l01\nrf24.c</SOURCEFILE><HEADERFILE>C:\Hard\Git\Rmodule\nrf24l01\nRF24L01.h</HEADERFILE><HEADERFILE>C:\Hard\Git\Rmodule\nrf24l01\nrf24.h</HEADERFILE><OTHERFILE>default\Rmodule.lss</OTHERFILE><OTHERFILE>default\Rmodule.map</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega8</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>Rmodule.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>main.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS/><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\Program Files\Atmel\AVR Tools\AVR Toolchain\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\Program Files\Atmel\AVR Tools\AVR Toolchain\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><ProjectFiles><Files><Name>C:\Hard\Git\Rmodule\nrf24l01\nRF24L01.h</Name><Name>C:\Hard\Git\Rmodule\nrf24l01\nrf24.h</Name><Name>C:\Hard\Git\Rmodule\main.c</Name><Name>C:\Hard\Git\Rmodule\nrf24l01\radioPinFunctions.c</Name><Name>C:\Hard\Git\Rmodule\nrf24l01\nrf24.c</Name></Files></ProjectFiles><IOView><usergroups/><sort sorted="0" column="0" ordername="0" orderaddress="0" ordergroup="0"/></IOView><Files><File00000><FileId>00000</FileId><FileName>main.c</FileName><Status>1</Status></File00000></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
|
||||
<AVRStudio><MANAGEMENT><ProjectName>Rmodule</ProjectName><Created>14-Nov-2013 11:48:57</Created><LastEdit>09-Dec-2013 21:08:58</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>14-Nov-2013 11:48:57</Created><Version>4</Version><Build>4, 19, 0, 730</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\Rmodule.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>c:\Hard\Git\Rmodule\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATmega8.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>C:\Hard\Git\Rmodule\nrf24l01\radioPinFunctions.c</SOURCEFILE><SOURCEFILE>C:\Hard\Git\Rmodule\nrf24l01\nrf24.c</SOURCEFILE><HEADERFILE>C:\Hard\Git\Rmodule\nrf24l01\nRF24L01.h</HEADERFILE><HEADERFILE>C:\Hard\Git\Rmodule\nrf24l01\nrf24.h</HEADERFILE><OTHERFILE>default\Rmodule.lss</OTHERFILE><OTHERFILE>default\Rmodule.map</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega8</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>Rmodule.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>main.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS/><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\Program Files\Atmel\AVR Tools\AVR Toolchain\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\Program Files\Atmel\AVR Tools\AVR Toolchain\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><ProjectFiles><Files><Name>C:\Hard\Git\Rmodule\nrf24l01\nRF24L01.h</Name><Name>C:\Hard\Git\Rmodule\nrf24l01\nrf24.h</Name><Name>c:\Hard\Git\Rmodule\main.c</Name><Name>C:\Hard\Git\Rmodule\nrf24l01\radioPinFunctions.c</Name><Name>C:\Hard\Git\Rmodule\nrf24l01\nrf24.c</Name></Files></ProjectFiles><IOView><usergroups/><sort sorted="0" column="0" ordername="1" orderaddress="1" ordergroup="1"/></IOView><Files><File00000><FileId>00000</FileId><FileName>main.c</FileName><Status>1</Status></File00000></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
|
||||
|
130
Rmodule/nrf24l01/nRF24L01.h
Normal file
130
Rmodule/nrf24l01/nRF24L01.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
/* Memory Map */
|
||||
#define CONFIG 0x00
|
||||
#define EN_AA 0x01
|
||||
#define EN_RXADDR 0x02
|
||||
#define SETUP_AW 0x03
|
||||
#define SETUP_RETR 0x04
|
||||
#define RF_CH 0x05
|
||||
#define RF_SETUP 0x06
|
||||
#define STATUS 0x07
|
||||
#define OBSERVE_TX 0x08
|
||||
#define CD 0x09
|
||||
#define RX_ADDR_P0 0x0A
|
||||
#define RX_ADDR_P1 0x0B
|
||||
#define RX_ADDR_P2 0x0C
|
||||
#define RX_ADDR_P3 0x0D
|
||||
#define RX_ADDR_P4 0x0E
|
||||
#define RX_ADDR_P5 0x0F
|
||||
#define TX_ADDR 0x10
|
||||
#define RX_PW_P0 0x11
|
||||
#define RX_PW_P1 0x12
|
||||
#define RX_PW_P2 0x13
|
||||
#define RX_PW_P3 0x14
|
||||
#define RX_PW_P4 0x15
|
||||
#define RX_PW_P5 0x16
|
||||
#define FIFO_STATUS 0x17
|
||||
#define DYNPD 0x1C
|
||||
|
||||
/* Bit Mnemonics */
|
||||
|
||||
/* configuratio nregister */
|
||||
#define MASK_RX_DR 6
|
||||
#define MASK_TX_DS 5
|
||||
#define MASK_MAX_RT 4
|
||||
#define EN_CRC 3
|
||||
#define CRCO 2
|
||||
#define PWR_UP 1
|
||||
#define PRIM_RX 0
|
||||
|
||||
/* enable auto acknowledgment */
|
||||
#define ENAA_P5 5
|
||||
#define ENAA_P4 4
|
||||
#define ENAA_P3 3
|
||||
#define ENAA_P2 2
|
||||
#define ENAA_P1 1
|
||||
#define ENAA_P0 0
|
||||
|
||||
/* enable rx addresses */
|
||||
#define ERX_P5 5
|
||||
#define ERX_P4 4
|
||||
#define ERX_P3 3
|
||||
#define ERX_P2 2
|
||||
#define ERX_P1 1
|
||||
#define ERX_P0 0
|
||||
|
||||
/* setup of address width */
|
||||
#define AW 0 /* 2 bits */
|
||||
|
||||
/* setup of auto re-transmission */
|
||||
#define ARD 4 /* 4 bits */
|
||||
#define ARC 0 /* 4 bits */
|
||||
|
||||
/* RF setup register */
|
||||
#define PLL_LOCK 4
|
||||
#define RF_DR 3
|
||||
#define RF_PWR 1 /* 2 bits */
|
||||
|
||||
/* general status register */
|
||||
#define RX_DR 6
|
||||
#define TX_DS 5
|
||||
#define MAX_RT 4
|
||||
#define RX_P_NO 1 /* 3 bits */
|
||||
#define TX_FULL 0
|
||||
|
||||
/* transmit observe register */
|
||||
#define PLOS_CNT 4 /* 4 bits */
|
||||
#define ARC_CNT 0 /* 4 bits */
|
||||
|
||||
/* fifo status */
|
||||
#define TX_REUSE 6
|
||||
#define FIFO_FULL 5
|
||||
#define TX_EMPTY 4
|
||||
#define RX_FULL 1
|
||||
#define RX_EMPTY 0
|
||||
|
||||
/* dynamic length */
|
||||
#define DPL_P0 0
|
||||
#define DPL_P1 1
|
||||
#define DPL_P2 2
|
||||
#define DPL_P3 3
|
||||
#define DPL_P4 4
|
||||
#define DPL_P5 5
|
||||
|
||||
/* Instruction Mnemonics */
|
||||
#define R_REGISTER 0x00 /* last 4 bits will indicate reg. address */
|
||||
#define W_REGISTER 0x20 /* last 4 bits will indicate reg. address */
|
||||
#define REGISTER_MASK 0x1F
|
||||
#define R_RX_PAYLOAD 0x61
|
||||
#define W_TX_PAYLOAD 0xA0
|
||||
#define FLUSH_TX 0xE1
|
||||
#define FLUSH_RX 0xE2
|
||||
#define REUSE_TX_PL 0xE3
|
||||
#define ACTIVATE 0x50
|
||||
#define R_RX_PL_WID 0x60
|
||||
#define NOP 0xFF
|
351
Rmodule/nrf24l01/nrf24.c
Normal file
351
Rmodule/nrf24l01/nrf24.c
Normal file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* “THE COFFEEWARE LICENSE” (Revision 1):
|
||||
* <ihsan@kehribar.me> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a coffee in return.
|
||||
* -----------------------------------------------------------------------------
|
||||
* This library is based on this library:
|
||||
* https://github.com/aaronds/arduino-nrf24l01
|
||||
* Which is based on this library:
|
||||
* http://www.tinkerer.eu/AVRLib/nRF24L01
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
#include "nrf24.h"
|
||||
|
||||
uint8_t payload_len;
|
||||
|
||||
/* init the hardware pins */
|
||||
void nrf24_init()
|
||||
{
|
||||
nrf24_setupPins();
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
/* configure the module */
|
||||
void nrf24_config(uint8_t channel, uint8_t pay_length)
|
||||
{
|
||||
/* Use static payload length ... */
|
||||
payload_len = pay_length;
|
||||
|
||||
// Set RF channel
|
||||
nrf24_configRegister(RF_CH,channel);
|
||||
|
||||
// Set length of incoming payload
|
||||
nrf24_configRegister(RX_PW_P0, 0x00); // Auto-ACK pipe ...
|
||||
nrf24_configRegister(RX_PW_P1, payload_len); // Data payload pipe
|
||||
nrf24_configRegister(RX_PW_P2, 0x00); // Pipe not used
|
||||
nrf24_configRegister(RX_PW_P3, 0x00); // Pipe not used
|
||||
nrf24_configRegister(RX_PW_P4, 0x00); // Pipe not used
|
||||
nrf24_configRegister(RX_PW_P5, 0x00); // Pipe not used
|
||||
|
||||
// 1 Mbps, TX gain: 0dbm
|
||||
nrf24_configRegister(RF_SETUP, (0<<RF_DR)|((0x03)<<RF_PWR));
|
||||
|
||||
// CRC enable, 1 byte CRC length
|
||||
nrf24_configRegister(CONFIG,nrf24_CONFIG);
|
||||
|
||||
// Auto Acknowledgment
|
||||
nrf24_configRegister(EN_AA,(1<<ENAA_P0)|(1<<ENAA_P1)|(0<<ENAA_P2)|(0<<ENAA_P3)|(0<<ENAA_P4)|(0<<ENAA_P5));
|
||||
|
||||
// Enable RX addresses
|
||||
nrf24_configRegister(EN_RXADDR,(1<<ERX_P0)|(1<<ERX_P1)|(0<<ERX_P2)|(0<<ERX_P3)|(0<<ERX_P4)|(0<<ERX_P5));
|
||||
|
||||
// Auto retransmit delay: 1000 us and Up to 15 retransmit trials
|
||||
nrf24_configRegister(SETUP_RETR,(0x04<<ARD)|(0x0F<<ARC));
|
||||
|
||||
// Dynamic length configurations: No dynamic length
|
||||
nrf24_configRegister(DYNPD,(0<<DPL_P0)|(0<<DPL_P1)|(0<<DPL_P2)|(0<<DPL_P3)|(0<<DPL_P4)|(0<<DPL_P5));
|
||||
|
||||
// Start listening
|
||||
nrf24_powerUpRx();
|
||||
}
|
||||
|
||||
/* Set the RX address */
|
||||
void nrf24_rx_address(uint8_t * adr)
|
||||
{
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
nrf24_writeRegister(RX_ADDR_P1,adr,nrf24_ADDR_LEN);
|
||||
nrf24_ce_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
/* Returns the payload length */
|
||||
uint8_t nrf24_payload_length()
|
||||
{
|
||||
return payload_len;
|
||||
}
|
||||
|
||||
/* Set the TX address */
|
||||
void nrf24_tx_address(uint8_t* adr)
|
||||
{
|
||||
/* RX_ADDR_P0 must be set to the sending addr for auto ack to work. */
|
||||
nrf24_writeRegister(RX_ADDR_P0,adr,nrf24_ADDR_LEN);
|
||||
nrf24_writeRegister(TX_ADDR,adr,nrf24_ADDR_LEN);
|
||||
}
|
||||
|
||||
/* Checks if data is available for reading */
|
||||
/* Returns 1 if data is ready ... */
|
||||
uint8_t nrf24_dataReady()
|
||||
{
|
||||
// See note in getData() function - just checking RX_DR isn't good enough
|
||||
uint8_t status = nrf24_getStatus();
|
||||
|
||||
// We can short circuit on RX_DR, but if it's not set, we still need
|
||||
// to check the FIFO for any pending packets
|
||||
if ( status & (1 << RX_DR) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return !nrf24_rxFifoEmpty();;
|
||||
}
|
||||
|
||||
/* Checks if receive FIFO is empty or not */
|
||||
uint8_t nrf24_rxFifoEmpty()
|
||||
{
|
||||
uint8_t fifoStatus;
|
||||
|
||||
nrf24_readRegister(FIFO_STATUS,&fifoStatus,1);
|
||||
|
||||
return (fifoStatus & (1 << RX_EMPTY));
|
||||
}
|
||||
|
||||
/* Returns the length of data waiting in the RX fifo */
|
||||
uint8_t nrf24_payloadLength()
|
||||
{
|
||||
uint8_t status;
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(R_RX_PL_WID);
|
||||
status = spi_transfer(0x00);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Reads payload bytes into data array */
|
||||
void nrf24_getData(uint8_t* data)
|
||||
{
|
||||
/* Pull down chip select */
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
|
||||
/* Send cmd to read rx payload */
|
||||
spi_transfer( R_RX_PAYLOAD );
|
||||
|
||||
/* Read payload */
|
||||
nrf24_transferSync(data,data,payload_len);
|
||||
|
||||
/* Pull up chip select */
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
|
||||
/* Reset status register */
|
||||
nrf24_configRegister(STATUS,(1<<RX_DR));
|
||||
}
|
||||
|
||||
/* Returns the number of retransmissions occured for the last message */
|
||||
uint8_t nrf24_retransmissionCount()
|
||||
{
|
||||
uint8_t rv;
|
||||
nrf24_readRegister(OBSERVE_TX,&rv,1);
|
||||
rv = rv & 0x0F;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Sends a data package to the default address. Be sure to send the correct
|
||||
// amount of bytes as configured as payload on the receiver.
|
||||
void nrf24_send(uint8_t* value)
|
||||
{
|
||||
/* Go to Standby-I first */
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
|
||||
/* Set to transmitter mode , Power up if needed */
|
||||
nrf24_powerUpTx();
|
||||
|
||||
/* Do we really need to flush TX fifo each time ? */
|
||||
#if 1
|
||||
/* Pull down chip select */
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
|
||||
/* Write cmd to flush transmit FIFO */
|
||||
spi_transfer(FLUSH_TX);
|
||||
|
||||
/* Pull up chip select */
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
#endif
|
||||
|
||||
/* Pull down chip select */
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
|
||||
/* Write cmd to write payload */
|
||||
spi_transfer(W_TX_PAYLOAD);
|
||||
|
||||
/* Write payload */
|
||||
nrf24_transmitSync(value,payload_len);
|
||||
|
||||
/* Pull up chip select */
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
|
||||
/* Start the transmission */
|
||||
nrf24_ce_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
uint8_t nrf24_isSending()
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
/* read the current status */
|
||||
status = nrf24_getStatus();
|
||||
|
||||
/* if sending successful (TX_DS) or max retries exceded (MAX_RT). */
|
||||
if((status & ((1 << TX_DS) | (1 << MAX_RT))))
|
||||
{
|
||||
return 0; /* false */
|
||||
}
|
||||
|
||||
return 1; /* true */
|
||||
|
||||
}
|
||||
|
||||
uint8_t nrf24_getStatus()
|
||||
{
|
||||
uint8_t rv;
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
rv = spi_transfer(NOP);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint8_t nrf24_lastMessageStatus()
|
||||
{
|
||||
uint8_t rv;
|
||||
|
||||
rv = nrf24_getStatus();
|
||||
|
||||
/* Transmission went OK */
|
||||
if((rv & ((1 << TX_DS))))
|
||||
{
|
||||
return NRF24_TRANSMISSON_OK;
|
||||
}
|
||||
/* Maximum retransmission count is reached */
|
||||
/* Last message probably went missing ... */
|
||||
else if((rv & ((1 << MAX_RT))))
|
||||
{
|
||||
return NRF24_MESSAGE_LOST;
|
||||
}
|
||||
/* Probably still sending ... */
|
||||
else
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void nrf24_powerUpRx()
|
||||
{
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(FLUSH_RX);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
|
||||
nrf24_configRegister(STATUS,(1<<RX_DR)|(1<<TX_DS)|(1<<MAX_RT));
|
||||
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(1<<PRIM_RX)));
|
||||
nrf24_ce_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
void nrf24_powerUpTx()
|
||||
{
|
||||
nrf24_configRegister(STATUS,(1<<RX_DR)|(1<<TX_DS)|(1<<MAX_RT));
|
||||
|
||||
nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(0<<PRIM_RX)));
|
||||
}
|
||||
|
||||
void nrf24_powerDown()
|
||||
{
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
nrf24_configRegister(CONFIG,nrf24_CONFIG);
|
||||
}
|
||||
|
||||
/* software spi routine */
|
||||
uint8_t spi_transfer(uint8_t tx)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t rx = 0;
|
||||
|
||||
nrf24_sck_digitalWrite(LOW);
|
||||
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
|
||||
if(tx & (1<<(7-i)))
|
||||
{
|
||||
nrf24_mosi_digitalWrite(HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrf24_mosi_digitalWrite(LOW);
|
||||
}
|
||||
|
||||
nrf24_sck_digitalWrite(HIGH);
|
||||
|
||||
rx = rx << 1;
|
||||
if(nrf24_miso_digitalRead())
|
||||
{
|
||||
rx |= 0x01;
|
||||
}
|
||||
|
||||
nrf24_sck_digitalWrite(LOW);
|
||||
|
||||
}
|
||||
|
||||
return rx;
|
||||
}
|
||||
|
||||
/* send and receive multiple bytes over SPI */
|
||||
void nrf24_transferSync(uint8_t* dataout,uint8_t* datain,uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
datain[i] = spi_transfer(dataout[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* send multiple bytes over SPI */
|
||||
void nrf24_transmitSync(uint8_t* dataout,uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
spi_transfer(dataout[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Clocks only one byte into the given nrf24 register */
|
||||
void nrf24_configRegister(uint8_t reg, uint8_t value)
|
||||
{
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
|
||||
spi_transfer(value);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
/* Read single register from nrf24 */
|
||||
void nrf24_readRegister(uint8_t reg, uint8_t* value, uint8_t len)
|
||||
{
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(R_REGISTER | (REGISTER_MASK & reg));
|
||||
nrf24_transferSync(value,value,len);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
/* Write to a single register of nrf24 */
|
||||
void nrf24_writeRegister(uint8_t reg, uint8_t* value, uint8_t len)
|
||||
{
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
|
||||
nrf24_transmitSync(value,len);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
}
|
116
Rmodule/nrf24l01/nrf24.h
Normal file
116
Rmodule/nrf24l01/nrf24.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* “THE COFFEEWARE LICENSE” (Revision 1):
|
||||
* <ihsan@kehribar.me> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a coffee in return.
|
||||
* -----------------------------------------------------------------------------
|
||||
* This library is based on this library:
|
||||
* https://github.com/aaronds/arduino-nrf24l01
|
||||
* Which is based on this library:
|
||||
* http://www.tinkerer.eu/AVRLib/nRF24L01
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef NRF24
|
||||
#define NRF24
|
||||
|
||||
#include "nRF24L01.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
|
||||
#define nrf24_ADDR_LEN 5
|
||||
#define nrf24_CONFIG ((1<<EN_CRC)|(0<<CRCO))
|
||||
|
||||
#define NRF24_TRANSMISSON_OK 0
|
||||
#define NRF24_MESSAGE_LOST 1
|
||||
|
||||
/* adjustment functions */
|
||||
void nrf24_init();
|
||||
void nrf24_rx_address(uint8_t* adr);
|
||||
void nrf24_tx_address(uint8_t* adr);
|
||||
void nrf24_config(uint8_t channel, uint8_t pay_length);
|
||||
|
||||
/* state check functions */
|
||||
uint8_t nrf24_dataReady();
|
||||
uint8_t nrf24_isSending();
|
||||
uint8_t nrf24_getStatus();
|
||||
uint8_t nrf24_rxFifoEmpty();
|
||||
|
||||
/* core TX / RX functions */
|
||||
void nrf24_send(uint8_t* value);
|
||||
void nrf24_getData(uint8_t* data);
|
||||
|
||||
/* use in dynamic length mode */
|
||||
uint8_t nrf24_payloadLength();
|
||||
|
||||
/* post transmission analysis */
|
||||
uint8_t nrf24_lastMessageStatus();
|
||||
uint8_t nrf24_retransmissionCount();
|
||||
|
||||
/* Returns the payload length */
|
||||
uint8_t nrf24_payload_length();
|
||||
|
||||
/* power management */
|
||||
void nrf24_powerUpRx();
|
||||
void nrf24_powerUpTx();
|
||||
void nrf24_powerDown();
|
||||
|
||||
/* low level interface ... */
|
||||
uint8_t spi_transfer(uint8_t tx);
|
||||
void nrf24_transmitSync(uint8_t* dataout,uint8_t len);
|
||||
void nrf24_transferSync(uint8_t* dataout,uint8_t* datain,uint8_t len);
|
||||
void nrf24_configRegister(uint8_t reg, uint8_t value);
|
||||
void nrf24_readRegister(uint8_t reg, uint8_t* value, uint8_t len);
|
||||
void nrf24_writeRegister(uint8_t reg, uint8_t* value, uint8_t len);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* You should implement the platform spesific functions in your code */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* In this function you should do the following things:
|
||||
* - Set MISO pin input
|
||||
* - Set MOSI pin output
|
||||
* - Set SCK pin output
|
||||
* - Set CSN pin output
|
||||
* - Set CE pin output */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_setupPins();
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* nrf24 CE pin control function
|
||||
* - state:1 => Pin HIGH
|
||||
* - state:0 => Pin LOW */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_ce_digitalWrite(uint8_t state);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* nrf24 CE pin control function
|
||||
* - state:1 => Pin HIGH
|
||||
* - state:0 => Pin LOW */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_csn_digitalWrite(uint8_t state);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* nrf24 SCK pin control function
|
||||
* - state:1 => Pin HIGH
|
||||
* - state:0 => Pin LOW */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_sck_digitalWrite(uint8_t state);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* nrf24 MOSI pin control function
|
||||
* - state:1 => Pin HIGH
|
||||
* - state:0 => Pin LOW */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_mosi_digitalWrite(uint8_t state);
|
||||
|
||||
/* -----------------------------------------*/
|
||||
/* nrf24 MISO pin read function */
|
||||
/* - returns: Non-zero if the pin is high */
|
||||
/* -----------------------------------------*/
|
||||
extern uint8_t nrf24_miso_digitalRead();
|
||||
|
||||
#endif
|
80
Rmodule/nrf24l01/radioPinFunctions.c
Normal file
80
Rmodule/nrf24l01/radioPinFunctions.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* “THE COFFEEWARE LICENSE” (Revision 1):
|
||||
* <ihsan@kehribar.me> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a coffee in return.
|
||||
* -----------------------------------------------------------------------------
|
||||
* Please define your platform spesific functions in this file ...
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#define set_bit(reg,bit) reg |= (1<<bit)
|
||||
#define clr_bit(reg,bit) reg &= ~(1<<bit)
|
||||
#define check_bit(reg,bit) (reg&(1<<bit))
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_setupPins()
|
||||
{
|
||||
set_bit(DDRB,0); // CE output
|
||||
set_bit(DDRB,1); // CSN output
|
||||
set_bit(DDRB,5); // SCK output
|
||||
set_bit(DDRB,3); // MOSI output
|
||||
clr_bit(DDRB,4); // MISO input
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_ce_digitalWrite(uint8_t state)
|
||||
{
|
||||
if(state)
|
||||
{
|
||||
set_bit(PORTB,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
clr_bit(PORTB,0);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_csn_digitalWrite(uint8_t state)
|
||||
{
|
||||
if(state)
|
||||
{
|
||||
set_bit(PORTB,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
clr_bit(PORTB,1);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_sck_digitalWrite(uint8_t state)
|
||||
{
|
||||
if(state)
|
||||
{
|
||||
set_bit(PORTB,5);
|
||||
}
|
||||
else
|
||||
{
|
||||
clr_bit(PORTB,5);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_mosi_digitalWrite(uint8_t state)
|
||||
{
|
||||
if(state)
|
||||
{
|
||||
set_bit(PORTB,3);
|
||||
}
|
||||
else
|
||||
{
|
||||
clr_bit(PORTB,3);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
uint8_t nrf24_miso_digitalRead()
|
||||
{
|
||||
return check_bit(PINB,4);
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
@ -1 +1 @@
|
||||
<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="ATMEGA8"/><Files><File00000 Name="C:\Hard\Git\Rmodule\main.c" Position="312 171 923 655" LineCol="6 0"/></Files></AVRWorkspace>
|
||||
<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="ATMEGA8"/><Files><File00000 Name="c:\Hard\Git\Rmodule\main.c" Position="262 96 1079 803" LineCol="26 1" State="Maximized"/></Files></AVRWorkspace>
|
||||
|
1
Smodule/Smodule.aps
Normal file
1
Smodule/Smodule.aps
Normal file
@ -0,0 +1 @@
|
||||
<AVRStudio><MANAGEMENT><ProjectName>Smodule</ProjectName><Created>04-Dec-2013 09:22:09</Created><LastEdit>08-Dec-2013 13:26:42</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>04-Dec-2013 09:22:09</Created><Version>4</Version><Build>4, 19, 0, 730</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\Smodule.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>c:\Hard\Git\Smodule\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATmega8.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>uart\uart_addon.c</SOURCEFILE><SOURCEFILE>uart\uart.c</SOURCEFILE><SOURCEFILE>nrf24l01\nrf24.c</SOURCEFILE><SOURCEFILE>nrf24l01\radioPinFunctions.c</SOURCEFILE><HEADERFILE>res\strings.h</HEADERFILE><HEADERFILE>uart\uart.h</HEADERFILE><HEADERFILE>uart\uart_addon.h</HEADERFILE><HEADERFILE>nrf24l01\nrf24.h</HEADERFILE><HEADERFILE>nrf24l01\nRF24L01.h</HEADERFILE><OTHERFILE>default\Smodule.lss</OTHERFILE><OTHERFILE>default\Smodule.map</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega8</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>Smodule.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS/><INCDIRS/><LIBDIRS/><LIBS/><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\Program Files\Atmel\AVR Tools\AVR Toolchain\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\Program Files\Atmel\AVR Tools\AVR Toolchain\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><ProjectFiles><Files><Name>c:\Hard\Git\Smodule\res\strings.h</Name><Name>c:\Hard\Git\Smodule\uart\uart.h</Name><Name>c:\Hard\Git\Smodule\uart\uart_addon.h</Name><Name>c:\Hard\Git\Smodule\nrf24l01\nrf24.h</Name><Name>c:\Hard\Git\Smodule\nrf24l01\nRF24L01.h</Name><Name>c:\Hard\Git\Smodule\main.c</Name><Name>c:\Hard\Git\Smodule\uart\uart_addon.c</Name><Name>c:\Hard\Git\Smodule\uart\uart.c</Name><Name>c:\Hard\Git\Smodule\nrf24l01\nrf24.c</Name><Name>c:\Hard\Git\Smodule\nrf24l01\radioPinFunctions.c</Name></Files></ProjectFiles><IOView><usergroups/><sort sorted="0" column="0" ordername="1" orderaddress="1" ordergroup="1"/></IOView><Files><File00000><FileId>00000</FileId><FileName>main.c</FileName><Status>1</Status></File00000><File00001><FileId>00001</FileId><FileName>res\strings.h</FileName><Status>1</Status></File00001></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
|
89
Smodule/default/Makefile
Normal file
89
Smodule/default/Makefile
Normal file
@ -0,0 +1,89 @@
|
||||
###############################################################################
|
||||
# Makefile for the project Smodule
|
||||
###############################################################################
|
||||
|
||||
## General Flags
|
||||
PROJECT = Smodule
|
||||
MCU = atmega8
|
||||
TARGET = Smodule.elf
|
||||
CC = avr-gcc
|
||||
|
||||
CPP = avr-g++
|
||||
|
||||
## Options common to compile, link and assembly rules
|
||||
COMMON = -mmcu=$(MCU)
|
||||
|
||||
## Compile options common for all C compilation units.
|
||||
CFLAGS = $(COMMON)
|
||||
CFLAGS += -Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d
|
||||
|
||||
## Assembly specific flags
|
||||
ASMFLAGS = $(COMMON)
|
||||
ASMFLAGS += $(CFLAGS)
|
||||
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
|
||||
|
||||
## Linker flags
|
||||
LDFLAGS = $(COMMON)
|
||||
LDFLAGS += -Wl,-Map=Smodule.map
|
||||
|
||||
|
||||
## Intel Hex file production flags
|
||||
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
|
||||
|
||||
HEX_EEPROM_FLAGS = -j .eeprom
|
||||
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
|
||||
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
|
||||
|
||||
|
||||
## Objects that must be built in order to link
|
||||
OBJECTS = main.o uart_addon.o uart.o nrf24.o radioPinFunctions.o
|
||||
|
||||
## Objects explicitly added by the user
|
||||
LINKONLYOBJECTS =
|
||||
|
||||
## Build
|
||||
all: $(TARGET) Smodule.hex Smodule.eep Smodule.lss size
|
||||
|
||||
## Compile
|
||||
main.o: ../main.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
uart_addon.o: ../uart/uart_addon.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
uart.o: ../uart/uart.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
nrf24.o: ../nrf24l01/nrf24.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
radioPinFunctions.o: ../nrf24l01/radioPinFunctions.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
##Link
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
|
||||
|
||||
%.hex: $(TARGET)
|
||||
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
|
||||
|
||||
%.eep: $(TARGET)
|
||||
-avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
|
||||
|
||||
%.lss: $(TARGET)
|
||||
avr-objdump -h -S $< > $@
|
||||
|
||||
size: ${TARGET}
|
||||
@echo
|
||||
@avr-size -C --mcu=${MCU} ${TARGET}
|
||||
|
||||
## Clean target
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -rf $(OBJECTS) Smodule.elf dep/* Smodule.hex Smodule.eep Smodule.lss Smodule.map
|
||||
|
||||
|
||||
## Other dependencies
|
||||
-include $(shell mkdir dep 2>NUL) $(wildcard dep/*)
|
||||
|
123
Smodule/main.c
Normal file
123
Smodule/main.c
Normal file
@ -0,0 +1,123 @@
|
||||
// Ïðîøèâêà äëÿ óäàëåííîãî ðàäèîìîäóëÿ
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <stdio.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "uart/uart.h"
|
||||
#include "uart/uart_addon.h"
|
||||
#include "res/strings.h"
|
||||
#include "nrf24l01/nrf24.h"
|
||||
|
||||
#define UART_BAUD_RATE 9600
|
||||
|
||||
unsigned char get_uart_char(void){
|
||||
unsigned int res;
|
||||
do{
|
||||
res = uart_getc();
|
||||
} while(res & UART_NO_DATA);
|
||||
return (unsigned char) res;
|
||||
}
|
||||
|
||||
static int get_uart_line(char *pbuf, int len_ln){
|
||||
int i = 0;
|
||||
unsigned char c;
|
||||
len_ln=len_ln-1;
|
||||
|
||||
while((c=get_uart_char()) != 0x0D && i<len_ln){
|
||||
uart_putc(c);
|
||||
pbuf[i] = c;
|
||||
i=i+1;
|
||||
}
|
||||
pbuf[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
typedef struct data_arr{
|
||||
uint8_t buffer[32];
|
||||
}data_array;
|
||||
|
||||
|
||||
uint8_t rx_mac[5] = {0xE7,0xE7,0xE7,0xE7,0xE7};
|
||||
uint8_t tx_mac[5] = {0xD7,0xD7,0xD7,0xD7,0xD7};
|
||||
uint8_t temp;
|
||||
|
||||
int main(void){
|
||||
|
||||
uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
|
||||
|
||||
/* initializes hardware pins */
|
||||
nrf24_init();
|
||||
|
||||
/* RF channel: #2 , payload length: 4 */
|
||||
nrf24_config(2,32);
|
||||
|
||||
/* Set the module's own address */
|
||||
nrf24_rx_address(rx_mac);
|
||||
|
||||
/* Set the transmit address */
|
||||
nrf24_tx_address(tx_mac);
|
||||
|
||||
sei();
|
||||
|
||||
data_array buff;
|
||||
char cmd[5];
|
||||
uint8_t i;
|
||||
unsigned int len_line=0;
|
||||
|
||||
uart_puts_p(CmdPrompt);
|
||||
|
||||
while(1){
|
||||
if (!(UCSRA & (1 << RXC))){
|
||||
len_line=get_uart_line(&cmd[0],sizeof(cmd));
|
||||
if (len_line>0){
|
||||
if (strcmp(cmd, CmdLD)==0){
|
||||
/* Automatically goes to TX mode */
|
||||
nrf24_send((uint8_t*) &cmd);
|
||||
|
||||
/* Wait for transmission to end */
|
||||
while(nrf24_isSending());
|
||||
|
||||
/* Make analysis on last tranmission attempt */
|
||||
temp = nrf24_lastMessageStatus();
|
||||
|
||||
if(temp == NRF24_TRANSMISSON_OK){
|
||||
uart_puts_p(TransOK);
|
||||
}else if(temp == NRF24_MESSAGE_LOST){
|
||||
uart_puts_p(TransLost);
|
||||
}
|
||||
|
||||
/* Retranmission count indicates the tranmission quality */
|
||||
temp = nrf24_retransmissionCount();
|
||||
uart_puts_p(ReTransCnt);
|
||||
uart_put_int(temp);
|
||||
|
||||
uart_puts_p(CmdPrompt);
|
||||
|
||||
/* Optionally, go back to RX mode ... */
|
||||
nrf24_powerUpRx();
|
||||
|
||||
/* Or you might want to power down after TX */
|
||||
// nrf24_powerDown();
|
||||
|
||||
/* Wait a little ... */
|
||||
_delay_ms(10);
|
||||
}
|
||||
if (strcmp(cmd, CmdHelp)==0){
|
||||
uart_puts_p(HelpTitle);
|
||||
uart_puts_p(HelpItem1);
|
||||
uart_puts_p(HelpItem2);
|
||||
uart_puts_p(CmdPrompt);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(nrf24_dataReady()){
|
||||
nrf24_getData((uint8_t *) &buff);
|
||||
for ( i=0; i < sizeof(buff.buffer); i++ ){
|
||||
uart_puthex_byte(buff.buffer[i]);
|
||||
uart_putc(' ');
|
||||
}
|
||||
uart_puts(CRLF);
|
||||
}
|
||||
}
|
||||
}
|
130
Smodule/nrf24l01/nRF24L01.h
Normal file
130
Smodule/nrf24l01/nRF24L01.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
/* Memory Map */
|
||||
#define CONFIG 0x00
|
||||
#define EN_AA 0x01
|
||||
#define EN_RXADDR 0x02
|
||||
#define SETUP_AW 0x03
|
||||
#define SETUP_RETR 0x04
|
||||
#define RF_CH 0x05
|
||||
#define RF_SETUP 0x06
|
||||
#define STATUS 0x07
|
||||
#define OBSERVE_TX 0x08
|
||||
#define CD 0x09
|
||||
#define RX_ADDR_P0 0x0A
|
||||
#define RX_ADDR_P1 0x0B
|
||||
#define RX_ADDR_P2 0x0C
|
||||
#define RX_ADDR_P3 0x0D
|
||||
#define RX_ADDR_P4 0x0E
|
||||
#define RX_ADDR_P5 0x0F
|
||||
#define TX_ADDR 0x10
|
||||
#define RX_PW_P0 0x11
|
||||
#define RX_PW_P1 0x12
|
||||
#define RX_PW_P2 0x13
|
||||
#define RX_PW_P3 0x14
|
||||
#define RX_PW_P4 0x15
|
||||
#define RX_PW_P5 0x16
|
||||
#define FIFO_STATUS 0x17
|
||||
#define DYNPD 0x1C
|
||||
|
||||
/* Bit Mnemonics */
|
||||
|
||||
/* configuratio nregister */
|
||||
#define MASK_RX_DR 6
|
||||
#define MASK_TX_DS 5
|
||||
#define MASK_MAX_RT 4
|
||||
#define EN_CRC 3
|
||||
#define CRCO 2
|
||||
#define PWR_UP 1
|
||||
#define PRIM_RX 0
|
||||
|
||||
/* enable auto acknowledgment */
|
||||
#define ENAA_P5 5
|
||||
#define ENAA_P4 4
|
||||
#define ENAA_P3 3
|
||||
#define ENAA_P2 2
|
||||
#define ENAA_P1 1
|
||||
#define ENAA_P0 0
|
||||
|
||||
/* enable rx addresses */
|
||||
#define ERX_P5 5
|
||||
#define ERX_P4 4
|
||||
#define ERX_P3 3
|
||||
#define ERX_P2 2
|
||||
#define ERX_P1 1
|
||||
#define ERX_P0 0
|
||||
|
||||
/* setup of address width */
|
||||
#define AW 0 /* 2 bits */
|
||||
|
||||
/* setup of auto re-transmission */
|
||||
#define ARD 4 /* 4 bits */
|
||||
#define ARC 0 /* 4 bits */
|
||||
|
||||
/* RF setup register */
|
||||
#define PLL_LOCK 4
|
||||
#define RF_DR 3
|
||||
#define RF_PWR 1 /* 2 bits */
|
||||
|
||||
/* general status register */
|
||||
#define RX_DR 6
|
||||
#define TX_DS 5
|
||||
#define MAX_RT 4
|
||||
#define RX_P_NO 1 /* 3 bits */
|
||||
#define TX_FULL 0
|
||||
|
||||
/* transmit observe register */
|
||||
#define PLOS_CNT 4 /* 4 bits */
|
||||
#define ARC_CNT 0 /* 4 bits */
|
||||
|
||||
/* fifo status */
|
||||
#define TX_REUSE 6
|
||||
#define FIFO_FULL 5
|
||||
#define TX_EMPTY 4
|
||||
#define RX_FULL 1
|
||||
#define RX_EMPTY 0
|
||||
|
||||
/* dynamic length */
|
||||
#define DPL_P0 0
|
||||
#define DPL_P1 1
|
||||
#define DPL_P2 2
|
||||
#define DPL_P3 3
|
||||
#define DPL_P4 4
|
||||
#define DPL_P5 5
|
||||
|
||||
/* Instruction Mnemonics */
|
||||
#define R_REGISTER 0x00 /* last 4 bits will indicate reg. address */
|
||||
#define W_REGISTER 0x20 /* last 4 bits will indicate reg. address */
|
||||
#define REGISTER_MASK 0x1F
|
||||
#define R_RX_PAYLOAD 0x61
|
||||
#define W_TX_PAYLOAD 0xA0
|
||||
#define FLUSH_TX 0xE1
|
||||
#define FLUSH_RX 0xE2
|
||||
#define REUSE_TX_PL 0xE3
|
||||
#define ACTIVATE 0x50
|
||||
#define R_RX_PL_WID 0x60
|
||||
#define NOP 0xFF
|
351
Smodule/nrf24l01/nrf24.c
Normal file
351
Smodule/nrf24l01/nrf24.c
Normal file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* “THE COFFEEWARE LICENSE” (Revision 1):
|
||||
* <ihsan@kehribar.me> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a coffee in return.
|
||||
* -----------------------------------------------------------------------------
|
||||
* This library is based on this library:
|
||||
* https://github.com/aaronds/arduino-nrf24l01
|
||||
* Which is based on this library:
|
||||
* http://www.tinkerer.eu/AVRLib/nRF24L01
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
#include "nrf24.h"
|
||||
|
||||
uint8_t payload_len;
|
||||
|
||||
/* init the hardware pins */
|
||||
void nrf24_init()
|
||||
{
|
||||
nrf24_setupPins();
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
/* configure the module */
|
||||
void nrf24_config(uint8_t channel, uint8_t pay_length)
|
||||
{
|
||||
/* Use static payload length ... */
|
||||
payload_len = pay_length;
|
||||
|
||||
// Set RF channel
|
||||
nrf24_configRegister(RF_CH,channel);
|
||||
|
||||
// Set length of incoming payload
|
||||
nrf24_configRegister(RX_PW_P0, 0x00); // Auto-ACK pipe ...
|
||||
nrf24_configRegister(RX_PW_P1, payload_len); // Data payload pipe
|
||||
nrf24_configRegister(RX_PW_P2, 0x00); // Pipe not used
|
||||
nrf24_configRegister(RX_PW_P3, 0x00); // Pipe not used
|
||||
nrf24_configRegister(RX_PW_P4, 0x00); // Pipe not used
|
||||
nrf24_configRegister(RX_PW_P5, 0x00); // Pipe not used
|
||||
|
||||
// 1 Mbps, TX gain: 0dbm
|
||||
nrf24_configRegister(RF_SETUP, (0<<RF_DR)|((0x03)<<RF_PWR));
|
||||
|
||||
// CRC enable, 1 byte CRC length
|
||||
nrf24_configRegister(CONFIG,nrf24_CONFIG);
|
||||
|
||||
// Auto Acknowledgment
|
||||
nrf24_configRegister(EN_AA,(1<<ENAA_P0)|(1<<ENAA_P1)|(0<<ENAA_P2)|(0<<ENAA_P3)|(0<<ENAA_P4)|(0<<ENAA_P5));
|
||||
|
||||
// Enable RX addresses
|
||||
nrf24_configRegister(EN_RXADDR,(1<<ERX_P0)|(1<<ERX_P1)|(0<<ERX_P2)|(0<<ERX_P3)|(0<<ERX_P4)|(0<<ERX_P5));
|
||||
|
||||
// Auto retransmit delay: 1000 us and Up to 15 retransmit trials
|
||||
nrf24_configRegister(SETUP_RETR,(0x04<<ARD)|(0x0F<<ARC));
|
||||
|
||||
// Dynamic length configurations: No dynamic length
|
||||
nrf24_configRegister(DYNPD,(0<<DPL_P0)|(0<<DPL_P1)|(0<<DPL_P2)|(0<<DPL_P3)|(0<<DPL_P4)|(0<<DPL_P5));
|
||||
|
||||
// Start listening
|
||||
nrf24_powerUpRx();
|
||||
}
|
||||
|
||||
/* Set the RX address */
|
||||
void nrf24_rx_address(uint8_t * adr)
|
||||
{
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
nrf24_writeRegister(RX_ADDR_P1,adr,nrf24_ADDR_LEN);
|
||||
nrf24_ce_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
/* Returns the payload length */
|
||||
uint8_t nrf24_payload_length()
|
||||
{
|
||||
return payload_len;
|
||||
}
|
||||
|
||||
/* Set the TX address */
|
||||
void nrf24_tx_address(uint8_t* adr)
|
||||
{
|
||||
/* RX_ADDR_P0 must be set to the sending addr for auto ack to work. */
|
||||
nrf24_writeRegister(RX_ADDR_P0,adr,nrf24_ADDR_LEN);
|
||||
nrf24_writeRegister(TX_ADDR,adr,nrf24_ADDR_LEN);
|
||||
}
|
||||
|
||||
/* Checks if data is available for reading */
|
||||
/* Returns 1 if data is ready ... */
|
||||
uint8_t nrf24_dataReady()
|
||||
{
|
||||
// See note in getData() function - just checking RX_DR isn't good enough
|
||||
uint8_t status = nrf24_getStatus();
|
||||
|
||||
// We can short circuit on RX_DR, but if it's not set, we still need
|
||||
// to check the FIFO for any pending packets
|
||||
if ( status & (1 << RX_DR) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return !nrf24_rxFifoEmpty();;
|
||||
}
|
||||
|
||||
/* Checks if receive FIFO is empty or not */
|
||||
uint8_t nrf24_rxFifoEmpty()
|
||||
{
|
||||
uint8_t fifoStatus;
|
||||
|
||||
nrf24_readRegister(FIFO_STATUS,&fifoStatus,1);
|
||||
|
||||
return (fifoStatus & (1 << RX_EMPTY));
|
||||
}
|
||||
|
||||
/* Returns the length of data waiting in the RX fifo */
|
||||
uint8_t nrf24_payloadLength()
|
||||
{
|
||||
uint8_t status;
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(R_RX_PL_WID);
|
||||
status = spi_transfer(0x00);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Reads payload bytes into data array */
|
||||
void nrf24_getData(uint8_t* data)
|
||||
{
|
||||
/* Pull down chip select */
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
|
||||
/* Send cmd to read rx payload */
|
||||
spi_transfer( R_RX_PAYLOAD );
|
||||
|
||||
/* Read payload */
|
||||
nrf24_transferSync(data,data,payload_len);
|
||||
|
||||
/* Pull up chip select */
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
|
||||
/* Reset status register */
|
||||
nrf24_configRegister(STATUS,(1<<RX_DR));
|
||||
}
|
||||
|
||||
/* Returns the number of retransmissions occured for the last message */
|
||||
uint8_t nrf24_retransmissionCount()
|
||||
{
|
||||
uint8_t rv;
|
||||
nrf24_readRegister(OBSERVE_TX,&rv,1);
|
||||
rv = rv & 0x0F;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Sends a data package to the default address. Be sure to send the correct
|
||||
// amount of bytes as configured as payload on the receiver.
|
||||
void nrf24_send(uint8_t* value)
|
||||
{
|
||||
/* Go to Standby-I first */
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
|
||||
/* Set to transmitter mode , Power up if needed */
|
||||
nrf24_powerUpTx();
|
||||
|
||||
/* Do we really need to flush TX fifo each time ? */
|
||||
#if 1
|
||||
/* Pull down chip select */
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
|
||||
/* Write cmd to flush transmit FIFO */
|
||||
spi_transfer(FLUSH_TX);
|
||||
|
||||
/* Pull up chip select */
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
#endif
|
||||
|
||||
/* Pull down chip select */
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
|
||||
/* Write cmd to write payload */
|
||||
spi_transfer(W_TX_PAYLOAD);
|
||||
|
||||
/* Write payload */
|
||||
nrf24_transmitSync(value,payload_len);
|
||||
|
||||
/* Pull up chip select */
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
|
||||
/* Start the transmission */
|
||||
nrf24_ce_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
uint8_t nrf24_isSending()
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
/* read the current status */
|
||||
status = nrf24_getStatus();
|
||||
|
||||
/* if sending successful (TX_DS) or max retries exceded (MAX_RT). */
|
||||
if((status & ((1 << TX_DS) | (1 << MAX_RT))))
|
||||
{
|
||||
return 0; /* false */
|
||||
}
|
||||
|
||||
return 1; /* true */
|
||||
|
||||
}
|
||||
|
||||
uint8_t nrf24_getStatus()
|
||||
{
|
||||
uint8_t rv;
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
rv = spi_transfer(NOP);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint8_t nrf24_lastMessageStatus()
|
||||
{
|
||||
uint8_t rv;
|
||||
|
||||
rv = nrf24_getStatus();
|
||||
|
||||
/* Transmission went OK */
|
||||
if((rv & ((1 << TX_DS))))
|
||||
{
|
||||
return NRF24_TRANSMISSON_OK;
|
||||
}
|
||||
/* Maximum retransmission count is reached */
|
||||
/* Last message probably went missing ... */
|
||||
else if((rv & ((1 << MAX_RT))))
|
||||
{
|
||||
return NRF24_MESSAGE_LOST;
|
||||
}
|
||||
/* Probably still sending ... */
|
||||
else
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void nrf24_powerUpRx()
|
||||
{
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(FLUSH_RX);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
|
||||
nrf24_configRegister(STATUS,(1<<RX_DR)|(1<<TX_DS)|(1<<MAX_RT));
|
||||
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(1<<PRIM_RX)));
|
||||
nrf24_ce_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
void nrf24_powerUpTx()
|
||||
{
|
||||
nrf24_configRegister(STATUS,(1<<RX_DR)|(1<<TX_DS)|(1<<MAX_RT));
|
||||
|
||||
nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(0<<PRIM_RX)));
|
||||
}
|
||||
|
||||
void nrf24_powerDown()
|
||||
{
|
||||
nrf24_ce_digitalWrite(LOW);
|
||||
nrf24_configRegister(CONFIG,nrf24_CONFIG);
|
||||
}
|
||||
|
||||
/* software spi routine */
|
||||
uint8_t spi_transfer(uint8_t tx)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t rx = 0;
|
||||
|
||||
nrf24_sck_digitalWrite(LOW);
|
||||
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
|
||||
if(tx & (1<<(7-i)))
|
||||
{
|
||||
nrf24_mosi_digitalWrite(HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrf24_mosi_digitalWrite(LOW);
|
||||
}
|
||||
|
||||
nrf24_sck_digitalWrite(HIGH);
|
||||
|
||||
rx = rx << 1;
|
||||
if(nrf24_miso_digitalRead())
|
||||
{
|
||||
rx |= 0x01;
|
||||
}
|
||||
|
||||
nrf24_sck_digitalWrite(LOW);
|
||||
|
||||
}
|
||||
|
||||
return rx;
|
||||
}
|
||||
|
||||
/* send and receive multiple bytes over SPI */
|
||||
void nrf24_transferSync(uint8_t* dataout,uint8_t* datain,uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
datain[i] = spi_transfer(dataout[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* send multiple bytes over SPI */
|
||||
void nrf24_transmitSync(uint8_t* dataout,uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
spi_transfer(dataout[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Clocks only one byte into the given nrf24 register */
|
||||
void nrf24_configRegister(uint8_t reg, uint8_t value)
|
||||
{
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
|
||||
spi_transfer(value);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
/* Read single register from nrf24 */
|
||||
void nrf24_readRegister(uint8_t reg, uint8_t* value, uint8_t len)
|
||||
{
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(R_REGISTER | (REGISTER_MASK & reg));
|
||||
nrf24_transferSync(value,value,len);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
}
|
||||
|
||||
/* Write to a single register of nrf24 */
|
||||
void nrf24_writeRegister(uint8_t reg, uint8_t* value, uint8_t len)
|
||||
{
|
||||
nrf24_csn_digitalWrite(LOW);
|
||||
spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
|
||||
nrf24_transmitSync(value,len);
|
||||
nrf24_csn_digitalWrite(HIGH);
|
||||
}
|
116
Smodule/nrf24l01/nrf24.h
Normal file
116
Smodule/nrf24l01/nrf24.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* “THE COFFEEWARE LICENSE” (Revision 1):
|
||||
* <ihsan@kehribar.me> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a coffee in return.
|
||||
* -----------------------------------------------------------------------------
|
||||
* This library is based on this library:
|
||||
* https://github.com/aaronds/arduino-nrf24l01
|
||||
* Which is based on this library:
|
||||
* http://www.tinkerer.eu/AVRLib/nRF24L01
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef NRF24
|
||||
#define NRF24
|
||||
|
||||
#include "nRF24L01.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
|
||||
#define nrf24_ADDR_LEN 5
|
||||
#define nrf24_CONFIG ((1<<EN_CRC)|(0<<CRCO))
|
||||
|
||||
#define NRF24_TRANSMISSON_OK 0
|
||||
#define NRF24_MESSAGE_LOST 1
|
||||
|
||||
/* adjustment functions */
|
||||
void nrf24_init();
|
||||
void nrf24_rx_address(uint8_t* adr);
|
||||
void nrf24_tx_address(uint8_t* adr);
|
||||
void nrf24_config(uint8_t channel, uint8_t pay_length);
|
||||
|
||||
/* state check functions */
|
||||
uint8_t nrf24_dataReady();
|
||||
uint8_t nrf24_isSending();
|
||||
uint8_t nrf24_getStatus();
|
||||
uint8_t nrf24_rxFifoEmpty();
|
||||
|
||||
/* core TX / RX functions */
|
||||
void nrf24_send(uint8_t* value);
|
||||
void nrf24_getData(uint8_t* data);
|
||||
|
||||
/* use in dynamic length mode */
|
||||
uint8_t nrf24_payloadLength();
|
||||
|
||||
/* post transmission analysis */
|
||||
uint8_t nrf24_lastMessageStatus();
|
||||
uint8_t nrf24_retransmissionCount();
|
||||
|
||||
/* Returns the payload length */
|
||||
uint8_t nrf24_payload_length();
|
||||
|
||||
/* power management */
|
||||
void nrf24_powerUpRx();
|
||||
void nrf24_powerUpTx();
|
||||
void nrf24_powerDown();
|
||||
|
||||
/* low level interface ... */
|
||||
uint8_t spi_transfer(uint8_t tx);
|
||||
void nrf24_transmitSync(uint8_t* dataout,uint8_t len);
|
||||
void nrf24_transferSync(uint8_t* dataout,uint8_t* datain,uint8_t len);
|
||||
void nrf24_configRegister(uint8_t reg, uint8_t value);
|
||||
void nrf24_readRegister(uint8_t reg, uint8_t* value, uint8_t len);
|
||||
void nrf24_writeRegister(uint8_t reg, uint8_t* value, uint8_t len);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* You should implement the platform spesific functions in your code */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* In this function you should do the following things:
|
||||
* - Set MISO pin input
|
||||
* - Set MOSI pin output
|
||||
* - Set SCK pin output
|
||||
* - Set CSN pin output
|
||||
* - Set CE pin output */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_setupPins();
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* nrf24 CE pin control function
|
||||
* - state:1 => Pin HIGH
|
||||
* - state:0 => Pin LOW */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_ce_digitalWrite(uint8_t state);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* nrf24 CE pin control function
|
||||
* - state:1 => Pin HIGH
|
||||
* - state:0 => Pin LOW */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_csn_digitalWrite(uint8_t state);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* nrf24 SCK pin control function
|
||||
* - state:1 => Pin HIGH
|
||||
* - state:0 => Pin LOW */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_sck_digitalWrite(uint8_t state);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* nrf24 MOSI pin control function
|
||||
* - state:1 => Pin HIGH
|
||||
* - state:0 => Pin LOW */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
extern void nrf24_mosi_digitalWrite(uint8_t state);
|
||||
|
||||
/* -----------------------------------------*/
|
||||
/* nrf24 MISO pin read function */
|
||||
/* - returns: Non-zero if the pin is high */
|
||||
/* -----------------------------------------*/
|
||||
extern uint8_t nrf24_miso_digitalRead();
|
||||
|
||||
#endif
|
80
Smodule/nrf24l01/radioPinFunctions.c
Normal file
80
Smodule/nrf24l01/radioPinFunctions.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* “THE COFFEEWARE LICENSE” (Revision 1):
|
||||
* <ihsan@kehribar.me> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a coffee in return.
|
||||
* -----------------------------------------------------------------------------
|
||||
* Please define your platform spesific functions in this file ...
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#define set_bit(reg,bit) reg |= (1<<bit)
|
||||
#define clr_bit(reg,bit) reg &= ~(1<<bit)
|
||||
#define check_bit(reg,bit) (reg&(1<<bit))
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_setupPins()
|
||||
{
|
||||
set_bit(DDRB,0); // CE output
|
||||
set_bit(DDRB,1); // CSN output
|
||||
set_bit(DDRB,5); // SCK output
|
||||
set_bit(DDRB,3); // MOSI output
|
||||
clr_bit(DDRB,4); // MISO input
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_ce_digitalWrite(uint8_t state)
|
||||
{
|
||||
if(state)
|
||||
{
|
||||
set_bit(PORTB,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
clr_bit(PORTB,0);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_csn_digitalWrite(uint8_t state)
|
||||
{
|
||||
if(state)
|
||||
{
|
||||
set_bit(PORTB,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
clr_bit(PORTB,1);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_sck_digitalWrite(uint8_t state)
|
||||
{
|
||||
if(state)
|
||||
{
|
||||
set_bit(PORTB,5);
|
||||
}
|
||||
else
|
||||
{
|
||||
clr_bit(PORTB,5);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_mosi_digitalWrite(uint8_t state)
|
||||
{
|
||||
if(state)
|
||||
{
|
||||
set_bit(PORTB,3);
|
||||
}
|
||||
else
|
||||
{
|
||||
clr_bit(PORTB,3);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
uint8_t nrf24_miso_digitalRead()
|
||||
{
|
||||
return check_bit(PINB,4);
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
17
Smodule/res/strings.h
Normal file
17
Smodule/res/strings.h
Normal file
@ -0,0 +1,17 @@
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#define CRLF "\r\n"
|
||||
#define CmdLD "ld"
|
||||
#define CmdHelp "h"
|
||||
|
||||
// Ñïèñîê êîìàíä
|
||||
const char HelpTitle[] PROGMEM = CRLF "Command list:";
|
||||
const char HelpItem1[] PROGMEM = CRLF CmdLD " - List devices";
|
||||
const char HelpItem2[] PROGMEM = CRLF CmdHelp " - Show this help";
|
||||
const char CmdPrompt[] PROGMEM = CRLF "# ";
|
||||
|
||||
// Ðàçíûå íóæíûå ñòðîêè
|
||||
const char ScanStr[] PROGMEM = CRLF "Scanning 1-wire bus" CRLF;
|
||||
const char TransOK[] PROGMEM = CRLF "> Tranmission went OK";
|
||||
const char TransLost[] PROGMEM = CRLF "> Message is lost ...";
|
||||
const char ReTransCnt[] PROGMEM = CRLF "> Retranmission count: ";
|
1
Smodule/smodule.aws
Normal file
1
Smodule/smodule.aws
Normal file
@ -0,0 +1 @@
|
||||
<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="ATMEGA8"/><Files><File00000 Name="c:\Hard\Git\Smodule\main.c" Position="268 123 883 611" LineCol="65 0"/><File00001 Name="c:\Hard\Git\Smodule\res\strings.h" Position="290 147 897 605" LineCol="17 0"/></Files></AVRWorkspace>
|
663
Smodule/uart/uart.c
Normal file
663
Smodule/uart/uart.c
Normal file
@ -0,0 +1,663 @@
|
||||
/*************************************************************************
|
||||
Title: Interrupt UART library with receive/transmit circular buffers
|
||||
Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
|
||||
File: $Id: uart.c,v 1.10 2013/06/02 07:27:04 peter Exp $
|
||||
Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher
|
||||
Hardware: any AVR with built-in UART,
|
||||
License: GNU General Public License
|
||||
|
||||
DESCRIPTION:
|
||||
An interrupt is generated when the UART has finished transmitting or
|
||||
receiving a byte. The interrupt handling routines use circular buffers
|
||||
for buffering received and transmitted data.
|
||||
|
||||
The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
|
||||
the buffer size in bytes. Note that these variables must be a
|
||||
power of 2.
|
||||
|
||||
USAGE:
|
||||
Refere to the header file uart.h for a description of the routines.
|
||||
See also example test_uart.c.
|
||||
|
||||
NOTES:
|
||||
Based on Atmel Application Note AVR306
|
||||
|
||||
LICENSE:
|
||||
Copyright (C) 2006 Peter Fleury
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
*************************************************************************/
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "uart.h"
|
||||
|
||||
|
||||
/*
|
||||
* constants and macros
|
||||
*/
|
||||
|
||||
/* size of RX/TX buffers */
|
||||
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
|
||||
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
|
||||
|
||||
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
|
||||
#error RX buffer size is not a power of 2
|
||||
#endif
|
||||
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
|
||||
#error TX buffer size is not a power of 2
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_AT90S2313__) \
|
||||
|| defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
|
||||
|| defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
|
||||
|| defined(__AVR_ATmega103__)
|
||||
/* old AVR classic or ATmega103 with one UART */
|
||||
#define AT90_UART
|
||||
#define UART0_RECEIVE_INTERRUPT UART_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT UART_UDRE_vect
|
||||
#define UART0_STATUS USR
|
||||
#define UART0_CONTROL UCR
|
||||
#define UART0_DATA UDR
|
||||
#define UART0_UDRIE UDRIE
|
||||
#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
|
||||
/* old AVR classic with one UART */
|
||||
#define AT90_UART
|
||||
#define UART0_RECEIVE_INTERRUPT UART_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT UART_UDRE_vect
|
||||
#define UART0_STATUS UCSRA
|
||||
#define UART0_CONTROL UCSRB
|
||||
#define UART0_DATA UDR
|
||||
#define UART0_UDRIE UDRIE
|
||||
#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
|
||||
|| defined(__AVR_ATmega323__)
|
||||
/* ATmega with one USART */
|
||||
#define ATMEGA_USART
|
||||
#define UART0_RECEIVE_INTERRUPT USART_RXC_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
|
||||
#define UART0_STATUS UCSRA
|
||||
#define UART0_CONTROL UCSRB
|
||||
#define UART0_DATA UDR
|
||||
#define UART0_UDRIE UDRIE
|
||||
#elif defined (__AVR_ATmega8515__) || defined(__AVR_ATmega8535__)
|
||||
#define ATMEGA_USART
|
||||
#define UART0_RECEIVE_INTERRUPT USART_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
|
||||
#define UART0_STATUS UCSRA
|
||||
#define UART0_CONTROL UCSRB
|
||||
#define UART0_DATA UDR
|
||||
#define UART0_UDRIE UDRIE
|
||||
#elif defined(__AVR_ATmega163__)
|
||||
/* ATmega163 with one UART */
|
||||
#define ATMEGA_UART
|
||||
#define UART0_RECEIVE_INTERRUPT UART_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT UART_UDRE_vect
|
||||
#define UART0_STATUS UCSRA
|
||||
#define UART0_CONTROL UCSRB
|
||||
#define UART0_DATA UDR
|
||||
#define UART0_UDRIE UDRIE
|
||||
#elif defined(__AVR_ATmega162__)
|
||||
/* ATmega with two USART */
|
||||
#define ATMEGA_USART0
|
||||
#define ATMEGA_USART1
|
||||
#define UART0_RECEIVE_INTERRUPT USART0_RXC_vect
|
||||
#define UART1_RECEIVE_INTERRUPT USART1_RXC_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
||||
#define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
|
||||
#define UART0_STATUS UCSR0A
|
||||
#define UART0_CONTROL UCSR0B
|
||||
#define UART0_DATA UDR0
|
||||
#define UART0_UDRIE UDRIE0
|
||||
#define UART1_STATUS UCSR1A
|
||||
#define UART1_CONTROL UCSR1B
|
||||
#define UART1_DATA UDR1
|
||||
#define UART1_UDRIE UDRIE1
|
||||
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
|
||||
/* ATmega with two USART */
|
||||
#define ATMEGA_USART0
|
||||
#define ATMEGA_USART1
|
||||
#define UART0_RECEIVE_INTERRUPT USART0_RX_vect
|
||||
#define UART1_RECEIVE_INTERRUPT USART1_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
||||
#define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
|
||||
#define UART0_STATUS UCSR0A
|
||||
#define UART0_CONTROL UCSR0B
|
||||
#define UART0_DATA UDR0
|
||||
#define UART0_UDRIE UDRIE0
|
||||
#define UART1_STATUS UCSR1A
|
||||
#define UART1_CONTROL UCSR1B
|
||||
#define UART1_DATA UDR1
|
||||
#define UART1_UDRIE UDRIE1
|
||||
#elif defined(__AVR_ATmega161__)
|
||||
/* ATmega with UART */
|
||||
#error "AVR ATmega161 currently not supported by this libaray !"
|
||||
#elif defined(__AVR_ATmega169__)
|
||||
/* ATmega with one USART */
|
||||
#define ATMEGA_USART
|
||||
#define UART0_RECEIVE_INTERRUPT USART0_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
||||
#define UART0_STATUS UCSRA
|
||||
#define UART0_CONTROL UCSRB
|
||||
#define UART0_DATA UDR
|
||||
#define UART0_UDRIE UDRIE
|
||||
#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) \
|
||||
|| defined(__AVR_ATmega3250__) || defined(__AVR_ATmega3290__) ||defined(__AVR_ATmega6450__) || defined(__AVR_ATmega6490__)
|
||||
/* ATmega with one USART */
|
||||
#define ATMEGA_USART0
|
||||
#define UART0_RECEIVE_INTERRUPT USART_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
|
||||
#define UART0_STATUS UCSR0A
|
||||
#define UART0_CONTROL UCSR0B
|
||||
#define UART0_DATA UDR0
|
||||
#define UART0_UDRIE UDRIE0
|
||||
#elif defined(__AVR_ATtiny2313__)
|
||||
#define ATMEGA_USART
|
||||
#define UART0_RECEIVE_INTERRUPT USART_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
|
||||
#define UART0_STATUS UCSRA
|
||||
#define UART0_CONTROL UCSRB
|
||||
#define UART0_DATA UDR
|
||||
#define UART0_UDRIE UDRIE
|
||||
#elif defined(__AVR_ATmega329__) || \
|
||||
defined(__AVR_ATmega649__) || \
|
||||
defined(__AVR_ATmega325__) || \
|
||||
defined(__AVR_ATmega645__)
|
||||
/* ATmega with one USART */
|
||||
#define ATMEGA_USART0
|
||||
#define UART0_RECEIVE_INTERRUPT USART0_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
||||
#define UART0_STATUS UCSR0A
|
||||
#define UART0_CONTROL UCSR0B
|
||||
#define UART0_DATA UDR0
|
||||
#define UART0_UDRIE UDRIE0
|
||||
#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega640__)
|
||||
/* ATmega with two USART */
|
||||
#define ATMEGA_USART0
|
||||
#define ATMEGA_USART1
|
||||
#define UART0_RECEIVE_INTERRUPT USART0_RX_vect
|
||||
#define UART1_RECEIVE_INTERRUPT USART1_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
||||
#define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
|
||||
#define UART0_STATUS UCSR0A
|
||||
#define UART0_CONTROL UCSR0B
|
||||
#define UART0_DATA UDR0
|
||||
#define UART0_UDRIE UDRIE0
|
||||
#define UART1_STATUS UCSR1A
|
||||
#define UART1_CONTROL UCSR1B
|
||||
#define UART1_DATA UDR1
|
||||
#define UART1_UDRIE UDRIE1
|
||||
#elif defined(__AVR_ATmega644__)
|
||||
/* ATmega with one USART */
|
||||
#define ATMEGA_USART0
|
||||
#define UART0_RECEIVE_INTERRUPT USART0_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
||||
#define UART0_STATUS UCSR0A
|
||||
#define UART0_CONTROL UCSR0B
|
||||
#define UART0_DATA UDR0
|
||||
#define UART0_UDRIE UDRIE0
|
||||
#elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__)
|
||||
/* ATmega with two USART */
|
||||
#define ATMEGA_USART0
|
||||
#define ATMEGA_USART1
|
||||
#define UART0_RECEIVE_INTERRUPT USART0_RX_vect
|
||||
#define UART1_RECEIVE_INTERRUPT USART1_RX_vect
|
||||
#define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
||||
#define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
|
||||
#define UART0_STATUS UCSR0A
|
||||
#define UART0_CONTROL UCSR0B
|
||||
#define UART0_DATA UDR0
|
||||
#define UART0_UDRIE UDRIE0
|
||||
#define UART1_STATUS UCSR1A
|
||||
#define UART1_CONTROL UCSR1B
|
||||
#define UART1_DATA UDR1
|
||||
#define UART1_UDRIE UDRIE1
|
||||
#else
|
||||
#error "no UART definition for MCU available"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* module global variables
|
||||
*/
|
||||
static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
|
||||
static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
|
||||
static volatile unsigned char UART_TxHead;
|
||||
static volatile unsigned char UART_TxTail;
|
||||
static volatile unsigned char UART_RxHead;
|
||||
static volatile unsigned char UART_RxTail;
|
||||
static volatile unsigned char UART_LastRxError;
|
||||
|
||||
#if defined( ATMEGA_USART1 )
|
||||
static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
|
||||
static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
|
||||
static volatile unsigned char UART1_TxHead;
|
||||
static volatile unsigned char UART1_TxTail;
|
||||
static volatile unsigned char UART1_RxHead;
|
||||
static volatile unsigned char UART1_RxTail;
|
||||
static volatile unsigned char UART1_LastRxError;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
ISR (UART0_RECEIVE_INTERRUPT)
|
||||
/*************************************************************************
|
||||
Function: UART Receive Complete interrupt
|
||||
Purpose: called when the UART has received a character
|
||||
**************************************************************************/
|
||||
{
|
||||
unsigned char tmphead;
|
||||
unsigned char data;
|
||||
unsigned char usr;
|
||||
unsigned char lastRxError;
|
||||
|
||||
|
||||
/* read UART status register and UART data register */
|
||||
usr = UART0_STATUS;
|
||||
data = UART0_DATA;
|
||||
|
||||
/* */
|
||||
#if defined( AT90_UART )
|
||||
lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
|
||||
#elif defined( ATMEGA_USART )
|
||||
lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
|
||||
#elif defined( ATMEGA_USART0 )
|
||||
lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
|
||||
#elif defined ( ATMEGA_UART )
|
||||
lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
|
||||
#endif
|
||||
|
||||
/* calculate buffer index */
|
||||
tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
|
||||
|
||||
if ( tmphead == UART_RxTail ) {
|
||||
/* error: receive buffer overflow */
|
||||
lastRxError = UART_BUFFER_OVERFLOW >> 8;
|
||||
}else{
|
||||
/* store new index */
|
||||
UART_RxHead = tmphead;
|
||||
/* store received data in buffer */
|
||||
UART_RxBuf[tmphead] = data;
|
||||
}
|
||||
UART_LastRxError |= lastRxError;
|
||||
}
|
||||
|
||||
|
||||
ISR (UART0_TRANSMIT_INTERRUPT)
|
||||
/*************************************************************************
|
||||
Function: UART Data Register Empty interrupt
|
||||
Purpose: called when the UART is ready to transmit the next byte
|
||||
**************************************************************************/
|
||||
{
|
||||
unsigned char tmptail;
|
||||
|
||||
|
||||
if ( UART_TxHead != UART_TxTail) {
|
||||
/* calculate and store new buffer index */
|
||||
tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
|
||||
UART_TxTail = tmptail;
|
||||
/* get one byte from buffer and write it to UART */
|
||||
UART0_DATA = UART_TxBuf[tmptail]; /* start transmission */
|
||||
}else{
|
||||
/* tx buffer empty, disable UDRE interrupt */
|
||||
UART0_CONTROL &= ~_BV(UART0_UDRIE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_init()
|
||||
Purpose: initialize UART and set baudrate
|
||||
Input: baudrate using macro UART_BAUD_SELECT()
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_init(unsigned int baudrate)
|
||||
{
|
||||
UART_TxHead = 0;
|
||||
UART_TxTail = 0;
|
||||
UART_RxHead = 0;
|
||||
UART_RxTail = 0;
|
||||
|
||||
#if defined( AT90_UART )
|
||||
/* set baud rate */
|
||||
UBRR = (unsigned char)baudrate;
|
||||
|
||||
/* enable UART receiver and transmmitter and receive complete interrupt */
|
||||
UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
|
||||
|
||||
#elif defined (ATMEGA_USART)
|
||||
/* Set baud rate */
|
||||
if ( baudrate & 0x8000 )
|
||||
{
|
||||
UART0_STATUS = (1<<U2X); //Enable 2x speed
|
||||
baudrate &= ~0x8000;
|
||||
}
|
||||
UBRRH = (unsigned char)(baudrate>>8);
|
||||
UBRRL = (unsigned char) baudrate;
|
||||
|
||||
/* Enable USART receiver and transmitter and receive complete interrupt */
|
||||
UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
|
||||
|
||||
/* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
||||
#ifdef URSEL
|
||||
UCSRC = (1<<URSEL)|(3<<UCSZ0);
|
||||
#else
|
||||
UCSRC = (3<<UCSZ0);
|
||||
#endif
|
||||
|
||||
#elif defined (ATMEGA_USART0 )
|
||||
/* Set baud rate */
|
||||
if ( baudrate & 0x8000 )
|
||||
{
|
||||
UART0_STATUS = (1<<U2X0); //Enable 2x speed
|
||||
baudrate &= ~0x8000;
|
||||
}
|
||||
UBRR0H = (unsigned char)(baudrate>>8);
|
||||
UBRR0L = (unsigned char) baudrate;
|
||||
|
||||
/* Enable USART receiver and transmitter and receive complete interrupt */
|
||||
UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
|
||||
|
||||
/* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
||||
#ifdef URSEL0
|
||||
UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
|
||||
#else
|
||||
UCSR0C = (3<<UCSZ00);
|
||||
#endif
|
||||
|
||||
#elif defined ( ATMEGA_UART )
|
||||
/* set baud rate */
|
||||
if ( baudrate & 0x8000 )
|
||||
{
|
||||
UART0_STATUS = (1<<U2X); //Enable 2x speed
|
||||
baudrate &= ~0x8000;
|
||||
}
|
||||
UBRRHI = (unsigned char)(baudrate>>8);
|
||||
UBRR = (unsigned char) baudrate;
|
||||
|
||||
/* Enable UART receiver and transmitter and receive complete interrupt */
|
||||
UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
|
||||
|
||||
#endif
|
||||
|
||||
}/* uart_init */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_getc()
|
||||
Purpose: return byte from ringbuffer
|
||||
Returns: lower byte: received byte from ringbuffer
|
||||
higher byte: last receive error
|
||||
**************************************************************************/
|
||||
unsigned int uart_getc(void)
|
||||
{
|
||||
unsigned char tmptail;
|
||||
unsigned char data;
|
||||
|
||||
|
||||
if ( UART_RxHead == UART_RxTail ) {
|
||||
return UART_NO_DATA; /* no data available */
|
||||
}
|
||||
|
||||
/* calculate /store buffer index */
|
||||
tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
|
||||
UART_RxTail = tmptail;
|
||||
|
||||
/* get data from receive buffer */
|
||||
data = UART_RxBuf[tmptail];
|
||||
|
||||
data = (UART_LastRxError << 8) + data;
|
||||
UART_LastRxError = 0;
|
||||
return data;
|
||||
|
||||
}/* uart_getc */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_putc()
|
||||
Purpose: write byte to ringbuffer for transmitting via UART
|
||||
Input: byte to be transmitted
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_putc(unsigned char data)
|
||||
{
|
||||
unsigned char tmphead;
|
||||
|
||||
|
||||
tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
|
||||
|
||||
while ( tmphead == UART_TxTail ){
|
||||
;/* wait for free space in buffer */
|
||||
}
|
||||
|
||||
UART_TxBuf[tmphead] = data;
|
||||
UART_TxHead = tmphead;
|
||||
|
||||
/* enable UDRE interrupt */
|
||||
UART0_CONTROL |= _BV(UART0_UDRIE);
|
||||
|
||||
}/* uart_putc */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_puts()
|
||||
Purpose: transmit string to UART
|
||||
Input: string to be transmitted
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_puts(const char *s )
|
||||
{
|
||||
while (*s)
|
||||
uart_putc(*s++);
|
||||
|
||||
}/* uart_puts */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_puts_p()
|
||||
Purpose: transmit string from program memory to UART
|
||||
Input: program memory string to be transmitted
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_puts_p(const char *progmem_s )
|
||||
{
|
||||
register char c;
|
||||
|
||||
while ( (c = pgm_read_byte(progmem_s++)) )
|
||||
uart_putc(c);
|
||||
|
||||
}/* uart_puts_p */
|
||||
|
||||
|
||||
/*
|
||||
* these functions are only for ATmegas with two USART
|
||||
*/
|
||||
#if defined( ATMEGA_USART1 )
|
||||
|
||||
ISR(UART1_RECEIVE_INTERRUPT)
|
||||
/*************************************************************************
|
||||
Function: UART1 Receive Complete interrupt
|
||||
Purpose: called when the UART1 has received a character
|
||||
**************************************************************************/
|
||||
{
|
||||
unsigned char tmphead;
|
||||
unsigned char data;
|
||||
unsigned char usr;
|
||||
unsigned char lastRxError;
|
||||
|
||||
|
||||
/* read UART status register and UART data register */
|
||||
usr = UART1_STATUS;
|
||||
data = UART1_DATA;
|
||||
|
||||
/* */
|
||||
lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
|
||||
|
||||
/* calculate buffer index */
|
||||
tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
|
||||
|
||||
if ( tmphead == UART1_RxTail ) {
|
||||
/* error: receive buffer overflow */
|
||||
lastRxError = UART_BUFFER_OVERFLOW >> 8;
|
||||
}else{
|
||||
/* store new index */
|
||||
UART1_RxHead = tmphead;
|
||||
/* store received data in buffer */
|
||||
UART1_RxBuf[tmphead] = data;
|
||||
}
|
||||
UART1_LastRxError |= lastRxError;
|
||||
}
|
||||
|
||||
|
||||
ISR(UART1_TRANSMIT_INTERRUPT)
|
||||
/*************************************************************************
|
||||
Function: UART1 Data Register Empty interrupt
|
||||
Purpose: called when the UART1 is ready to transmit the next byte
|
||||
**************************************************************************/
|
||||
{
|
||||
unsigned char tmptail;
|
||||
|
||||
|
||||
if ( UART1_TxHead != UART1_TxTail) {
|
||||
/* calculate and store new buffer index */
|
||||
tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
|
||||
UART1_TxTail = tmptail;
|
||||
/* get one byte from buffer and write it to UART */
|
||||
UART1_DATA = UART1_TxBuf[tmptail]; /* start transmission */
|
||||
}else{
|
||||
/* tx buffer empty, disable UDRE interrupt */
|
||||
UART1_CONTROL &= ~_BV(UART1_UDRIE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart1_init()
|
||||
Purpose: initialize UART1 and set baudrate
|
||||
Input: baudrate using macro UART_BAUD_SELECT()
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart1_init(unsigned int baudrate)
|
||||
{
|
||||
UART1_TxHead = 0;
|
||||
UART1_TxTail = 0;
|
||||
UART1_RxHead = 0;
|
||||
UART1_RxTail = 0;
|
||||
|
||||
|
||||
/* Set baud rate */
|
||||
if ( baudrate & 0x8000 )
|
||||
{
|
||||
UART1_STATUS = (1<<U2X1); //Enable 2x speed
|
||||
baudrate &= ~0x8000;
|
||||
}
|
||||
UBRR1H = (unsigned char)(baudrate>>8);
|
||||
UBRR1L = (unsigned char) baudrate;
|
||||
|
||||
/* Enable USART receiver and transmitter and receive complete interrupt */
|
||||
UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
|
||||
|
||||
/* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
||||
#ifdef URSEL1
|
||||
UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
|
||||
#else
|
||||
UCSR1C = (3<<UCSZ10);
|
||||
#endif
|
||||
}/* uart_init */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart1_getc()
|
||||
Purpose: return byte from ringbuffer
|
||||
Returns: lower byte: received byte from ringbuffer
|
||||
higher byte: last receive error
|
||||
**************************************************************************/
|
||||
unsigned int uart1_getc(void)
|
||||
{
|
||||
unsigned char tmptail;
|
||||
unsigned char data;
|
||||
|
||||
|
||||
if ( UART1_RxHead == UART1_RxTail ) {
|
||||
return UART_NO_DATA; /* no data available */
|
||||
}
|
||||
|
||||
/* calculate /store buffer index */
|
||||
tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
|
||||
UART1_RxTail = tmptail;
|
||||
|
||||
/* get data from receive buffer */
|
||||
data = UART1_RxBuf[tmptail];
|
||||
|
||||
data = (UART1_LastRxError << 8) + data;
|
||||
UART1_LastRxError = 0;
|
||||
return data;
|
||||
|
||||
}/* uart1_getc */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart1_putc()
|
||||
Purpose: write byte to ringbuffer for transmitting via UART
|
||||
Input: byte to be transmitted
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart1_putc(unsigned char data)
|
||||
{
|
||||
unsigned char tmphead;
|
||||
|
||||
|
||||
tmphead = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
|
||||
|
||||
while ( tmphead == UART1_TxTail ){
|
||||
;/* wait for free space in buffer */
|
||||
}
|
||||
|
||||
UART1_TxBuf[tmphead] = data;
|
||||
UART1_TxHead = tmphead;
|
||||
|
||||
/* enable UDRE interrupt */
|
||||
UART1_CONTROL |= _BV(UART1_UDRIE);
|
||||
|
||||
}/* uart1_putc */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart1_puts()
|
||||
Purpose: transmit string to UART1
|
||||
Input: string to be transmitted
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart1_puts(const char *s )
|
||||
{
|
||||
while (*s)
|
||||
uart1_putc(*s++);
|
||||
|
||||
}/* uart1_puts */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart1_puts_p()
|
||||
Purpose: transmit string from program memory to UART1
|
||||
Input: program memory string to be transmitted
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart1_puts_p(const char *progmem_s )
|
||||
{
|
||||
register char c;
|
||||
|
||||
while ( (c = pgm_read_byte(progmem_s++)) )
|
||||
uart1_putc(c);
|
||||
|
||||
}/* uart1_puts_p */
|
||||
|
||||
|
||||
#endif
|
195
Smodule/uart/uart.h
Normal file
195
Smodule/uart/uart.h
Normal file
@ -0,0 +1,195 @@
|
||||
#ifndef UART_H
|
||||
#define UART_H
|
||||
/************************************************************************
|
||||
Title: Interrupt UART library with receive/transmit circular buffers
|
||||
Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
|
||||
File: $Id: uart.h,v 1.12 2012/11/19 19:52:27 peter Exp $
|
||||
Software: AVR-GCC 4.1, AVR Libc 1.4
|
||||
Hardware: any AVR with built-in UART, tested on AT90S8515 & ATmega8 at 4 Mhz
|
||||
License: GNU General Public License
|
||||
Usage: see Doxygen manual
|
||||
|
||||
LICENSE:
|
||||
Copyright (C) 2006 Peter Fleury
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @defgroup pfleury_uart UART Library
|
||||
* @code #include <uart.h> @endcode
|
||||
*
|
||||
* @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers.
|
||||
*
|
||||
* This library can be used to transmit and receive data through the built in UART.
|
||||
*
|
||||
* An interrupt is generated when the UART has finished transmitting or
|
||||
* receiving a byte. The interrupt handling routines use circular buffers
|
||||
* for buffering received and transmitted data.
|
||||
*
|
||||
* The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE constants define
|
||||
* the size of the circular buffers in bytes. Note that these constants must be a power of 2.
|
||||
* You may need to adapt this constants to your target and your application by adding
|
||||
* CDEFS += -DUART_RX_BUFFER_SIZE=nn -DUART_RX_BUFFER_SIZE=nn to your Makefile.
|
||||
*
|
||||
* @note Based on Atmel Application Note AVR306
|
||||
* @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury
|
||||
*/
|
||||
|
||||
/**@{*/
|
||||
|
||||
|
||||
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
|
||||
#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** constants and macros
|
||||
*/
|
||||
|
||||
/** @brief UART Baudrate Expression
|
||||
* @param xtalcpu system clock in Mhz, e.g. 4000000UL for 4Mhz
|
||||
* @param baudrate baudrate in bps, e.g. 1200, 2400, 9600
|
||||
*/
|
||||
#define UART_BAUD_SELECT(baudRate,xtalCpu) (((xtalCpu) + 8UL * (baudRate)) / (16UL * (baudRate)) -1UL)
|
||||
|
||||
/** @brief UART Baudrate Expression for ATmega double speed mode
|
||||
* @param xtalcpu system clock in Mhz, e.g. 4000000UL for 4Mhz
|
||||
* @param baudrate baudrate in bps, e.g. 1200, 2400, 9600
|
||||
*/
|
||||
#define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate,xtalCpu) ( ((((xtalCpu) + 4UL * (baudRate)) / (8UL * (baudRate)) -1UL)) | 0x8000)
|
||||
|
||||
|
||||
/** Size of the circular receive buffer, must be power of 2 */
|
||||
#ifndef UART_RX_BUFFER_SIZE
|
||||
#define UART_RX_BUFFER_SIZE 32
|
||||
#endif
|
||||
/** Size of the circular transmit buffer, must be power of 2 */
|
||||
#ifndef UART_TX_BUFFER_SIZE
|
||||
#define UART_TX_BUFFER_SIZE 32
|
||||
#endif
|
||||
|
||||
/* test if the size of the circular buffers fits into SRAM */
|
||||
#if ( (UART_RX_BUFFER_SIZE+UART_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) )
|
||||
#error "size of UART_RX_BUFFER_SIZE + UART_TX_BUFFER_SIZE larger than size of SRAM"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** high byte error return code of uart_getc()
|
||||
*/
|
||||
#define UART_FRAME_ERROR 0x1000 /* Framing Error by UART */
|
||||
#define UART_OVERRUN_ERROR 0x0800 /* Overrun condition by UART */
|
||||
#define UART_PARITY_ERROR 0x0400 /* Parity Error by UART */
|
||||
#define UART_BUFFER_OVERFLOW 0x0200 /* receive ringbuffer overflow */
|
||||
#define UART_NO_DATA 0x0100 /* no receive data available */
|
||||
|
||||
|
||||
/*
|
||||
** function prototypes
|
||||
*/
|
||||
|
||||
/**
|
||||
@brief Initialize UART and set baudrate
|
||||
@param baudrate Specify baudrate using macro UART_BAUD_SELECT()
|
||||
@return none
|
||||
*/
|
||||
extern void uart_init(unsigned int baudrate);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get received byte from ringbuffer
|
||||
*
|
||||
* Returns in the lower byte the received character and in the
|
||||
* higher byte the last receive error.
|
||||
* UART_NO_DATA is returned when no data is available.
|
||||
*
|
||||
* @param void
|
||||
* @return lower byte: received byte from ringbuffer
|
||||
* @return higher byte: last receive status
|
||||
* - \b 0 successfully received data from UART
|
||||
* - \b UART_NO_DATA
|
||||
* <br>no receive data available
|
||||
* - \b UART_BUFFER_OVERFLOW
|
||||
* <br>Receive ringbuffer overflow.
|
||||
* We are not reading the receive buffer fast enough,
|
||||
* one or more received character have been dropped
|
||||
* - \b UART_OVERRUN_ERROR
|
||||
* <br>Overrun condition by UART.
|
||||
* A character already present in the UART UDR register was
|
||||
* not read by the interrupt handler before the next character arrived,
|
||||
* one or more received characters have been dropped.
|
||||
* - \b UART_FRAME_ERROR
|
||||
* <br>Framing Error by UART
|
||||
*/
|
||||
extern unsigned int uart_getc(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put byte to ringbuffer for transmitting via UART
|
||||
* @param data byte to be transmitted
|
||||
* @return none
|
||||
*/
|
||||
extern void uart_putc(unsigned char data);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put string to ringbuffer for transmitting via UART
|
||||
*
|
||||
* The string is buffered by the uart library in a circular buffer
|
||||
* and one character at a time is transmitted to the UART using interrupts.
|
||||
* Blocks if it can not write the whole string into the circular buffer.
|
||||
*
|
||||
* @param s string to be transmitted
|
||||
* @return none
|
||||
*/
|
||||
extern void uart_puts(const char *s );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put string from program memory to ringbuffer for transmitting via UART.
|
||||
*
|
||||
* The string is buffered by the uart library in a circular buffer
|
||||
* and one character at a time is transmitted to the UART using interrupts.
|
||||
* Blocks if it can not write the whole string into the circular buffer.
|
||||
*
|
||||
* @param s program memory string to be transmitted
|
||||
* @return none
|
||||
* @see uart_puts_P
|
||||
*/
|
||||
extern void uart_puts_p(const char *s );
|
||||
|
||||
/**
|
||||
* @brief Macro to automatically put a string constant into program memory
|
||||
*/
|
||||
#define uart_puts_P(__s) uart_puts_p(PSTR(__s))
|
||||
|
||||
|
||||
|
||||
/** @brief Initialize USART1 (only available on selected ATmegas) @see uart_init */
|
||||
extern void uart1_init(unsigned int baudrate);
|
||||
/** @brief Get received byte of USART1 from ringbuffer. (only available on selected ATmega) @see uart_getc */
|
||||
extern unsigned int uart1_getc(void);
|
||||
/** @brief Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_putc */
|
||||
extern void uart1_putc(unsigned char data);
|
||||
/** @brief Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts */
|
||||
extern void uart1_puts(const char *s );
|
||||
/** @brief Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts_p */
|
||||
extern void uart1_puts_p(const char *s );
|
||||
/** @brief Macro to automatically put a string constant into program memory */
|
||||
#define uart1_puts_P(__s) uart1_puts_p(PSTR(__s))
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
||||
#endif // UART_H
|
||||
|
118
Smodule/uart/uart_addon.c
Normal file
118
Smodule/uart/uart_addon.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*************************************************************************
|
||||
Title: UART addon-library
|
||||
Author: Martin Thomas <eversmith@heizung-thomas.de>
|
||||
http://www.siwawi.arubi.uni-kl.de/avr_projects
|
||||
Software: AVR-GCC 3.3/3.4, Peter Fleury's UART-Library
|
||||
|
||||
DESCRIPTION:
|
||||
|
||||
USAGE:
|
||||
Refere to the header file uart_addon.h for a description of the routines.
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <avr/io.h>
|
||||
#include "uart.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_put_int()
|
||||
Purpose: transmit integer as ASCII to UART
|
||||
Input: integer value
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_put_int( const int val )
|
||||
{
|
||||
char buffer[10];
|
||||
uart_puts( itoa( val, buffer, 10 ) );
|
||||
} /* uart_puti */
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_put_longint()
|
||||
Purpose: transmit long integer as ASCII to UART
|
||||
Input: integer value
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_put_longint( const long int val )
|
||||
{
|
||||
char buffer[15];
|
||||
uart_puts( ltoa( val, buffer, 10 ) );
|
||||
} /* uart_puti */
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_put_ulongint()
|
||||
Purpose: transmit long integer as ASCII to UART
|
||||
Input: integer value
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_put_ulongint( const unsigned long int val )
|
||||
{
|
||||
char buffer[15];
|
||||
uart_puts( utoa( val, buffer, 10 ) );
|
||||
} /* uart_puti */
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_puthex_nibble()
|
||||
Purpose: transmit lower nibble as ASCII-hex to UART
|
||||
Input: byte value
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_puthex_nibble(const unsigned char b)
|
||||
{
|
||||
unsigned char c = b & 0x0f;
|
||||
if ( c > 9 ) {
|
||||
c += 'A'-10;
|
||||
}
|
||||
else {
|
||||
c += '0';
|
||||
}
|
||||
uart_putc(c);
|
||||
} /* uart_puthex_nibble */
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_puthex_byte()
|
||||
Purpose: transmit upper and lower nibble as ASCII-hex to UART
|
||||
Input: byte value
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_puthex_byte( const unsigned char b )
|
||||
{
|
||||
uart_puthex_nibble( b >> 4 );
|
||||
uart_puthex_nibble( b );
|
||||
} /* uart_puthex_byte */
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_puthex_long()
|
||||
Purpose: transmit unsigned long as ASCII-hex to UART
|
||||
Input: uint32_t value
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_puthex_long( const unsigned long l )
|
||||
{
|
||||
uart_puthex_byte( (unsigned char)( l >> 24 ) );
|
||||
uart_puthex_byte( (unsigned char)( l >> 16 ) );
|
||||
uart_puthex_byte( (unsigned char)( l >> 8 ) );
|
||||
uart_puthex_byte( (unsigned char)( l ) );
|
||||
} /* uart_puthex_byte */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Function: uart_putbin_byte()
|
||||
Purpose: transmit byte as ASCII-bin to UART
|
||||
Input: byte value
|
||||
Returns: none
|
||||
**************************************************************************/
|
||||
void uart_putbin_byte( const unsigned char b )
|
||||
{
|
||||
signed char i;
|
||||
for ( i= 7;i >= 0;i-- ) {
|
||||
if ( b & ( 1 << i ) ) {
|
||||
uart_putc( '1' );
|
||||
}
|
||||
else {
|
||||
uart_putc( '0' );
|
||||
}
|
||||
}
|
||||
} /* uart_putbin_byte */
|
121
Smodule/uart/uart_addon.h
Normal file
121
Smodule/uart/uart_addon.h
Normal file
@ -0,0 +1,121 @@
|
||||
#ifndef UART_ADDON_H
|
||||
#define UART_ADDON_H
|
||||
/************************************************************************
|
||||
Title: UART addon-library
|
||||
Author: Martin Thomas <eversmith@heizung-thomas.de>
|
||||
http://www.siwawi.arubi.uni-kl.de/avr_projects
|
||||
Software: AVR-GCC 3.3/3.4, Peter Fleury's UART-Library
|
||||
************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup UART library-addon
|
||||
* @code #include <uart_addon.h> @endcode
|
||||
*
|
||||
* @brief Additional functions for send numbers as decimal and hex to UART
|
||||
*
|
||||
* @note needs Peter Fleury's UART-Library http://jump.to/fleury
|
||||
* @author Martin Thomas eversmith@heizung-thomas.de
|
||||
*/
|
||||
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* @brief Put long integer to ringbuffer for transmitting via UART.
|
||||
*
|
||||
* The integer is converted to a string which is buffered by the uart
|
||||
* library in a circular buffer and one character at a time is transmitted
|
||||
* to the UART using interrupts.
|
||||
*
|
||||
* @param value to transfer
|
||||
* @return none
|
||||
* @see uart_puts_p
|
||||
*/
|
||||
extern void uart_put_longint( long int i );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put unsigned long integer to ringbuffer for transmitting via UART.
|
||||
*
|
||||
* The integer is converted to a string which is buffered by the uart
|
||||
* library in a circular buffer and one character at a time is transmitted
|
||||
* to the UART using interrupts.
|
||||
*
|
||||
* @param value to transfer
|
||||
* @return none
|
||||
* @see uart_puts_p
|
||||
*/
|
||||
extern void uart_put_ulongint( unsigned long int i );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put integer to ringbuffer for transmitting via UART.
|
||||
*
|
||||
* The integer is converted to a string which is buffered by the uart
|
||||
* library in a circular buffer and one character at a time is transmitted
|
||||
* to the UART using interrupts.
|
||||
*
|
||||
* @param value to transfer
|
||||
* @return none
|
||||
* @see uart_puts_p
|
||||
*/
|
||||
extern void uart_put_int( int i );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put nibble as hex to ringbuffer for transmit via UART.
|
||||
*
|
||||
* The lower nibble of the parameter is convertet to correspondig
|
||||
* hex-char and put in a circular buffer and one character at a time
|
||||
* is transmitted to the UART using interrupts.
|
||||
*
|
||||
* @param value to transfer (byte, only lower nibble converted)
|
||||
* @return none
|
||||
* @see uart_putc
|
||||
*/
|
||||
extern void uart_puthex_nibble( const unsigned char b );
|
||||
|
||||
/**
|
||||
* @brief Put byte as hex to ringbuffer for transmit via UART.
|
||||
*
|
||||
* The upper and lower nibble of the parameter are convertet to
|
||||
* correspondig hex-chars and put in a circular buffer and one
|
||||
* character at a time is transmitted to the UART using interrupts.
|
||||
*
|
||||
* @param value to transfer
|
||||
* @return none
|
||||
* @see uart_puthex_nibble
|
||||
*/
|
||||
extern void uart_puthex_byte( const unsigned char b );
|
||||
|
||||
/**
|
||||
* @brief Put unsigned long as ASCII to ringbuffer for transmit via UART.
|
||||
*
|
||||
* @param value to transfer
|
||||
* @return none
|
||||
* @see none
|
||||
*/
|
||||
extern void uart_puthex_long( unsigned long l );
|
||||
|
||||
/**
|
||||
* @brief Put byte as bin to ringbuffer for transmit via UART.
|
||||
*
|
||||
* @param value to transfer
|
||||
* @return none
|
||||
* @see uart_putc
|
||||
*/
|
||||
extern void uart_putbin_byte( const unsigned char b );
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* UART_ADDON_H */
|
||||
|
Loading…
Reference in New Issue
Block a user