148 lines
3.6 KiB
C
Executable File
148 lines
3.6 KiB
C
Executable File
/*
|
|
* cc110x.c
|
|
*
|
|
* Created on: Jul 20, 2012
|
|
* Author: tkl
|
|
*/
|
|
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
#include "board.h"
|
|
#include "stack.h"
|
|
#include "queue.h"
|
|
#include "thread.h"
|
|
#include "schedule.h"
|
|
#include "irq.h"
|
|
#include "sys_tick.h"
|
|
#include "cc110x.h"
|
|
|
|
static volatile bool tx_condition;
|
|
extern volatile struct thread_context *current_thread;
|
|
|
|
static void it_cb(const struct cc110x *cc110x, enum cc110x_it_type it_type);
|
|
|
|
int cc110x_open(const struct cc110x *cc110x)
|
|
{
|
|
if(NULL == cc110x)
|
|
return (-1);
|
|
|
|
tx_condition = false;
|
|
cc110x->fp->init(cc110x);
|
|
cc110x->fp->set_it_callback(cc110x->arch_dep_device, it_cb, cc110x);
|
|
cc110x_set_radio_mode(cc110x, CC110X_RADIO_MODE_PWD);
|
|
cc110x_write_pa_table(cc110x);
|
|
return (0);
|
|
}
|
|
|
|
int cc110x_close(const struct cc110x *cc110x)
|
|
{
|
|
cc110x_set_radio_mode(cc110x, CC110X_RADIO_MODE_PWD);
|
|
blocking_read_wakeup(cc110x);
|
|
return 0;
|
|
}
|
|
|
|
void cc110x_set_radio_mode(const struct cc110x *cc110x,
|
|
enum cc110x_radio_mode mode)
|
|
{
|
|
if(NULL == cc110x) {
|
|
return;
|
|
}
|
|
*(cc110x->radio_mode) = mode;
|
|
enum cc110x_strobe_cmd cmd = STROBE_SIDLE;
|
|
switch(mode) {
|
|
case CC110X_RADIO_MODE_NONE: return;
|
|
case CC110X_RADIO_MODE_IDLE: cmd = STROBE_SIDLE; break;
|
|
case CC110X_RADIO_MODE_RX: cmd = STROBE_SRX; break;
|
|
case CC110X_RADIO_MODE_TX: cmd = STROBE_STX; break;
|
|
case CC110X_RADIO_MODE_PWD: cmd = STROBE_SPWD; break;
|
|
}
|
|
cc110x->fp->strobe(cc110x->arch_dep_device, cmd);
|
|
}
|
|
|
|
enum cc110x_radio_mode cc110x_get_radio_mode(const struct cc110x *cc110x)
|
|
{
|
|
if(NULL == cc110x)
|
|
return (CC110X_RADIO_MODE_NONE);
|
|
return (*(cc110x->radio_mode));
|
|
}
|
|
|
|
void cc110x_write_pa_table(const struct cc110x *cc110x)
|
|
{
|
|
if(NULL == cc110x)
|
|
return;
|
|
cc110x->fp->write_pa_table(cc110x->arch_dep_device);
|
|
}
|
|
|
|
void cc110x_strobe(const struct cc110x *cc110x, enum cc110x_strobe_cmd cmd)
|
|
{
|
|
if(NULL == cc110x)
|
|
return;
|
|
cc110x->fp->strobe(cc110x->arch_dep_device, cmd);
|
|
}
|
|
|
|
int cc110x_write(const struct cc110x *cc110x, const char *buffer,
|
|
int size)
|
|
{
|
|
enum cc110x_radio_mode mode;
|
|
int ret;
|
|
if((NULL == cc110x) || (NULL == buffer))
|
|
return (-1);
|
|
mode = cc110x_get_radio_mode(cc110x);
|
|
cc110x_set_radio_mode(cc110x, CC110X_RADIO_MODE_IDLE);
|
|
cc110x_strobe(cc110x, STROBE_SFTX);
|
|
ret = cc110x->fp->write(cc110x->arch_dep_device, buffer, size);
|
|
tx_condition = true;
|
|
cc110x_set_radio_mode(cc110x, CC110X_RADIO_MODE_TX);
|
|
while(tx_condition);
|
|
cc110x_set_radio_mode(cc110x, CC110X_RADIO_MODE_IDLE);
|
|
cc110x_strobe(cc110x, STROBE_SFTX);
|
|
cc110x_set_radio_mode(cc110x, mode);
|
|
return (ret);
|
|
}
|
|
|
|
int cc110x_read(const struct cc110x *cc110x, char *buffer, int size)
|
|
{
|
|
int ret;
|
|
unsigned int irq;
|
|
if((NULL == cc110x) || (NULL == buffer))
|
|
return (-1);
|
|
if(0 == cc110x_get_rx_count(cc110x)) {
|
|
irq = disable_irq();
|
|
current_thread->status = THREAD_STATUS_BLOCKING;
|
|
current_thread->wakeup_blocking_source = (void*) cc110x;
|
|
restore_irq(irq);
|
|
schedule();
|
|
}
|
|
enum cc110x_radio_mode mode = cc110x_get_radio_mode(cc110x);
|
|
cc110x_set_radio_mode(cc110x, CC110X_RADIO_MODE_IDLE);
|
|
ret = cc110x_get_rx_count(cc110x);
|
|
ret = cc110x->fp->read(cc110x->arch_dep_device, buffer, ret);
|
|
cc110x_strobe(cc110x, STROBE_SFRX);
|
|
cc110x_set_radio_mode(cc110x, mode);
|
|
return (ret);
|
|
}
|
|
|
|
int cc110x_get_rx_count(const struct cc110x *cc110x)
|
|
{
|
|
if(NULL == cc110x)
|
|
return (-1);
|
|
return (cc110x->fp->get_rx_count(cc110x->arch_dep_device));
|
|
}
|
|
|
|
static void it_cb(const struct cc110x *cc110x,
|
|
enum cc110x_it_type it_type)
|
|
{
|
|
if(NULL == cc110x)
|
|
return;
|
|
switch(it_type) {
|
|
case IT_TYPE_NONE:
|
|
break;
|
|
case IT_TYPE_RX_COMPLETE:
|
|
blocking_read_wakeup(cc110x);
|
|
break;
|
|
case IT_TYPE_TX_COMPLETE:
|
|
tx_condition = false;
|
|
break;
|
|
}
|
|
}
|