completely redid PWM: Now calculate 'microprograms', i.e. pairs of
[moodlight.git] / rfm12.c
CommitLineData
ff29bc2b 1/* $Id: rfm12.c,v 1.2 2010/07/24 20:55:48 simimeie Exp $
c95cbd3f 2 * Functions for communicating with the rfm12(b) module
3 */
4
5#include <avr/io.h>
6#include "rfm12.h"
7
8/* Unfortunately, the manufacturer documentation for chip and module is
9 * almost unreadable crap.
10 * This one is better: http://www.mikrocontroller.net/articles/RFM12
11 */
12/* Note: the signal is inverted, thus pulling this high DEselects the chip */
13#define spi_ss_hi() { PORTC |= _BV(0); }
14/* Consequently, this SELECTS the chip */
15#define spi_ss_lo() { PORTC &= (uint8_t)~_BV(0); }
16
ff29bc2b 17/* write and (at the same time) read a word from RFM12.
18 * The module uses 16 bit commands and replies that are
19 * synchronous to the command - except for the status read.
20 * Note: This does not handle chip select! */
21static uint16_t rfm12_spi_wrword(uint16_t v) {
22 uint16_t res;
c95cbd3f 23 /* Start transmission */
ff29bc2b 24 SPDR = v >> 8;
c95cbd3f 25 /* Wait for transmission complete */
26 while ((SPSR & _BV(SPIF)) == 0) {
27 }
ff29bc2b 28 res = (uint16_t)(SPDR) << 8;
29 SPDR = v & 0xff;
30 /* Wait for transmission complete */
c95cbd3f 31 while ((SPSR & _BV(SPIF)) == 0) {
32 }
ff29bc2b 33 res |= SPDR & 0xff;
34 return res;
35}
36
37void rfm12_sendcommand(uint16_t cmd) {
38 spi_ss_lo();
39 rfm12_spi_wrword(cmd);
40 spi_ss_hi();
41}
42
43uint32_t rfm12_readstatus(void) {
44 uint32_t res;
45 spi_ss_lo();
46 res = (uint32_t)rfm12_spi_wrword(0x0000) << 16;
47 res |= rfm12_spi_wrword(0x0000);
48 spi_ss_hi();
49 return res;
c95cbd3f 50}
51
52void rfm12_init(void) {
53 /* Set MOSI, SCK and SS output, MISO input */
ff29bc2b 54 /* Frickel Alert: Also set PB2 output. It is not used, but noise on the
55 * pin could reset our SPI mode to slave (!!!) if it is left as input. */
56 DDRB |= _BV(3) | _BV(5) | _BV(2);
c95cbd3f 57 DDRC |= _BV(0);
58 DDRB &= (uint8_t)~_BV(4);
59 spi_ss_hi();
ff29bc2b 60#if (CPUFREQ <= 10000000UL)
c95cbd3f 61 /* Enable SPI, Master, set clock rate fck/4.
62 * This works as long as our own clockrate is below 10 MHz - because
63 * 2.5 MHz is the maximum the rfm12b can do. */
64 SPCR |= _BV(SPE) | _BV(MSTR);
ff29bc2b 65#else
66 /* For higher clock rates set fck/16. */
67 SPCR |= _BV(SPE) | _BV(MSTR) | _BV(SPR0);
68#endif /* CPUFREQ */
69 /* Now send some initialization commands. */
70 /* Mostly taken over from http://www.joachim-neu.de/post/70/rfm12b-868/
71 * Seems to be mostly black magic anyways. */
72 rfm12_sendcommand(0x80E7); /* EL, EF, 868band, 12.0pF */
73 rfm12_sendcommand(0x8219); /* !er, !ebb, !ET, ES, EX, !eb, !ew, DC */
74 /* Frequency setting: 0xAnnn; the 12 nnn-bits of value are
75 * calculated like this: v = ((freq / 20) - 43) * 4000
76 */
77 rfm12_sendcommand(0xA7BC); /* 869,900 MHz */
78 rfm12_sendcommand(0xC647); /* 4.8kbps FIXME? */
79 rfm12_sendcommand(0x94C0); /* VDI, FAST, 67kHz, 0dBm, -103dBm */
80 rfm12_sendcommand(0xC2AC); /* AL, !ml, DIG, DQD4 */
81 rfm12_sendcommand(0xCA81);//FIFO8,SYNC,!ff,DR
82 rfm12_sendcommand(0xCED4);//SYNC=2DD4;
83 rfm12_sendcommand(0xC483);//@PWR,NO RSTRIC,!st,!fi,OE,EN
84 rfm12_sendcommand(0x9820);// !mp,45kHz,MAX OUT*/
85 rfm12_sendcommand(0xCC77);//OB1,OB0, LPX,!ddy,DDIT,BW0
86 rfm12_sendcommand(0xE000);//NOT USE
87 rfm12_sendcommand(0xC800);//NOT USE
88 rfm12_sendcommand(0xC040);//1.66MHz,2.2V
c95cbd3f 89}
This page took 0.05671 seconds and 4 git commands to generate.