#include "rv8564.h"
#include "I2C.h"
-// TODO(henrik) The request to the I2C is done throuh a immediateRequest, this perhaps needs to be changed because
-// its bad if the battery monitor has hold of the I2C bus.
module RV8564P
{
provides interface RV8564 as RTC;
// TODO(henrik) Exactly how is the RTC connected to mulle, what is the functionallity of GeneralIO?
// Maybe there is only a init needed because the chip is always on?
+ uses interface GeneralIO as CLKOE;
+ uses interface GeneralIO as CLKOUT;
uses interface GeneralIO;
uses interface GpioInterrupt;
uses interface I2CPacket<TI2CBasicAddr> as I2C;
}
implementation
{
- async command void RTC.on()
+
+ enum
+ {
+ OFF,
+ IDLE,
+ READING,
+ WRITING
+ };
+ norace uint8_t state = OFF;
+ norace uint8_t read_register;
+ uint8_t read_register_value;
+ uint8_t write_buffer[2];
+
+ command error_t RTC.on()
{
- call GeneralIO.makeOutput();
- call GeneralIO.set();
+ if (state != OFF)
+ {
+ return SUCCESS;
+ }
+ state = IDLE;
+ return SUCCESS;
}
- async command void RTC.off()
+ command error_t RTC.off()
{
- call GeneralIO.clr();
- call GeneralIO.makeInput();
+ if (state == OFF)
+ {
+ return SUCCESS;
+ }
+ else if (state != IDLE)
+ {
+ return FAIL;
+ }
+ call CLKOE.clr();
+ call CLKOUT.clr();
+ return SUCCESS;
}
- async command bool RTC.isOn()
+ command bool RTC.isOn()
{
- return (call GeneralIO.get() && call GeneralIO.isOutput());
+ return ((state != OFF) ? true : false);
}
- async command void RTC.enableInterrupt()
+ command void RTC.enableCLKOUT()
+ {
+ call CLKOUT.makeInput();
+ call CLKOUT.clr();
+ call CLKOE.makeOutput();
+ call CLKOE.set();
+ }
+ command void RTC.enableInterrupt()
{
call GpioInterrupt.enableFallingEdge();
}
- async command void RTC.disableInterrupt()
+ command void RTC.disableInterrupt()
{
call GpioInterrupt.disable();
}
-
- async command uint8_t RTC.readRegister(uint16_t reg)
+
+ command error_t RTC.readRegister(uint8_t reg)
{
uint8_t val;
- atomic
+ if (state != IDLE)
+ {
+ return FAIL;
+ }
+ state = READING;
+ read_register = reg;
+ call I2CResource.request();
+ return SUCCESS;
+ }
+
+ command error_t RTC.writeRegister(uint8_t reg, uint8_t value)
+ {
+ if (state != IDLE)
{
- if (call I2CResource.immediateRequest() == SUCCESS)
+ return FAIL;
+ }
+ state = WRITING;
+ write_buffer[0] = reg;
+ write_buffer[1] = value;
+ call I2CResource.request();
+ return SUCCESS;
+ }
+
+ event void I2CResource.granted()
+ {
+ atomic {
+ if (state == READING)
{
- call I2C.write(I2C_START, RV8564_WR_ADDR, 1, (uint8_t*)®);
- call I2C.read(I2C_START | I2C_STOP, RV8564_RD_ADDR, 1, &val);
- call I2CResource.release();
+ call I2C.write(I2C_START, RV8564_ADDR, 1, &read_register);
}
- }
- return val;
+ else if (state == WRITING)
+ {
+ call I2C.write(I2C_START | I2C_STOP, RV8564_ADDR, 2, write_buffer);
+ }
+ }
}
- async command void RTC.writeRegister(uint16_t reg, uint8_t value)
+ async event void GpioInterrupt.fired()
+ {
+ signal RTC.fired();
+ }
+
+ async event void I2C.readDone(error_t error, uint16_t addr, uint8_t length, uint8_t* data)
{
- uint8_t wr[2] = {reg, value};
atomic
{
- if (call I2CResource.immediateRequest() == SUCCESS)
+ if (state == READING && data == &read_register_value)
{
- call I2C.write(I2C_START | I2C_STOP, RV8564_WR_ADDR, 2, wr);
+ state = IDLE;
call I2CResource.release();
- }
+ signal RTC.readRegisterDone(read_register_value, read_register);
+ }
}
}
- event void I2CResource.granted()
+ async event void I2C.writeDone(error_t error, uint16_t addr, uint8_t length, uint8_t* data)
{
- // TODO(henrik) Insert communication code here.
- }
-
- async event void GpioInterrupt.fired()
- {
- signal RTC.fired();
+ if (state == READING)
+ {
+ call I2C.read(I2C_START | I2C_STOP, RV8564_ADDR, 1, &read_register_value);
+ }
+ else if (state == WRITING)
+ {
+ state = IDLE;
+ call I2CResource.release();
+ signal RTC.writeRegisterDone(write_buffer[0]);
+ }
}
- default async event void RTC.fired() { }
- async event void I2C.readDone(error_t error, uint16_t addr, uint8_t length, uint8_t* data) {}
- async event void I2C.writeDone(error_t error, uint16_t addr, uint8_t length, uint8_t* data) {}
+ default async event void RTC.readRegisterDone(uint8_t val, uint8_t reg) {}
+ default async event void RTC.writeRegisterDone(uint8_t reg) {}
+ default async event void RTC.fired() { }
}