File Name : main.c
#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_uart.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "PCF8563.h"
#include "nrf_delay.h"
/* UART buffer size */
#define UART_TX_BUF_SIZE 256
#define UART_RX_BUF_SIZE 1
#warning "!**** ARE YOU ABSOLUTELY SURE YOU HAVE CHOSEN
THE CORRECT SCL AND SDA PINS? ****!"
#define DEVICE_SCL_PIN 5
#define DEVICE_SDA_PIN 6
nrf_drv_twi_t twi_instance = NRF_DRV_TWI_INSTANCE(0);
uint8_t device_address = 0; // Address used to temporarily
store the current address being checked
bool device_found = false;
/**
* @brief UART events
handler.
*/
static void uart_events_handler(app_uart_evt_t * p_event)
{
switch
(p_event->evt_type)
{
case
APP_UART_COMMUNICATION_ERROR:
APP_ERROR_HANDLER(p_event->data.error_communication);
break;
case
APP_UART_FIFO_ERROR:
APP_ERROR_HANDLER(p_event->data.error_code);
break;
default:
break;
}
}
/**
* @brief UART
initialization.
*/
static void uart_config(void)
{
uint32_t err_code;
const
app_uart_comm_params_t comm_params =
{
RX_PIN_NUMBER,
TX_PIN_NUMBER,
RTS_PIN_NUMBER,
CTS_PIN_NUMBER,
APP_UART_FLOW_CONTROL_DISABLED,
false,
UART_BAUDRATE_BAUDRATE_Baud115200
};
APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_events_handler,
APP_IRQ_PRIORITY_LOW,
err_code);
APP_ERROR_CHECK(err_code);
}
/**
* @brief TWI events
handler.
*/
void twi_handler(nrf_drv_twi_evt_t const * p_event, void *
p_context)
{
switch(p_event->type)
{
case
NRF_DRV_TWI_EVT_DONE:
// If
EVT_DONE (event done) is received a device is found and responding on that
particular address
//printf("\r\n!****************************!\r\nDevice found at 7-bit
address: %#x!\r\n!****************************!\r\n\r\n", device_address);
//device_found = true;
break;
case
NRF_DRV_TWI_EVT_ADDRESS_NACK:
printf("No address ACK on address: %#x!\r\n", device_address);
break;
case
NRF_DRV_TWI_EVT_DATA_NACK:
printf("No data ACK on address: %#x!\r\n", device_address);
break;
default:
break;
}
}
/**
* @brief UART
initialization.
*/
void twi_init (void)
{
ret_code_t
err_code;
const
nrf_drv_twi_config_t twi_config = {
.scl = DEVICE_SCL_PIN,
.sda = DEVICE_SDA_PIN,
.frequency = NRF_TWI_FREQ_400K,
.interrupt_priority
= APP_IRQ_PRIORITY_HIGH
};
err_code =
nrf_drv_twi_init(&twi_instance, &twi_config, twi_handler, NULL);
APP_ERROR_CHECK(err_code);
nrf_drv_twi_enable(&twi_instance);
}
/**
* @brief Function for
main application entry.
*/
int main(void)
{
date_time_t dt;
nrf_gpio_cfg_output(LED_1);
nrf_gpio_pin_set(LED_1);
uart_config();
printf("PCF8563 RTC Test...........\r\n");
twi_init();
Initialize_PCF8563();
nrf_delay_ms(1000); // nrf_delay_ms(1000);
dt.month
= 7; // December
dt.day = 18;
// 31
dt.year = 17;
// 2006
dt.hours = 11;
// 23 hours (11pm in 24-hour time)
dt.minutes =
49; // 59 minutes
dt.seconds =
45; // 50 seconds
dt.weekday =
0; // 0 = Sunday, 1 = Monday, etc.
PCF8563_set_datetime(&dt);
while(1){
nrf_delay_ms(1000);
PCF8563_read_datetime(&dt);
printf("Time:
%d:%d:%d\r\n", dt.hours,dt.minutes,dt.seconds);
printf("Date:
%d:%d:%d\r\n", dt.day,dt.month,dt.year);
}
}
/** @} */
File Name : PCF8563.c
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h"
#include "string.h"
#include "PCF8563.h"
nrf_drv_twi_t twi_dist_pcf8563 = NRF_DRV_TWI_INSTANCE(0);
uint8_t _rm_bcd(uint8_t data);
uint8_t _get_bcd(uint8_t data);
//======================================================================================
uint8_t bin2bcd(uint8_t binary_value)
{
uint8_t temp;
uint8_t retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens
digit by doing multiple subtraction
// of 10 from the
binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the
ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
//====================================================================================================
// Input range - 00 to 99.
uint8_t bcd2bin(uint8_t bcd_value)
{
uint8_t temp;
temp = bcd_value;
// Shifting upper
digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits
for the upper digit.
temp &= 0x78;
// Now return: (Tens
* 8) + (Tens * 2) + Ones
return(temp + (temp
>> 2) + (bcd_value & 0x0f));
/*
temp=bcd_value;
bcd_value=(temp>>4)*10;
bcd_value=bcd_value+(temp&0x0F);
return
bcd_value;
*/
}
//======================================================================================
void PCF8563_writeReg(uint8_t W_reg, uint8_t value)
{
ret_code_t ret;
do
{
uint8_t
buffer[2]; /* Addr + data */
buffer[0] =
W_reg;
buffer[1] = value;
ret =
nrf_drv_twi_tx(&twi_dist_pcf8563, I2C_PCF8563_SLAVE_ADDR , buffer, 2,
false);
}while (0);
nrf_delay_ms(5);
}
//======================================================================================
uint8_t PCF8563_readReg(uint8_t W_reg)
{
ret_code_t ret;
uint8_t W_data;
do
{
ret =
nrf_drv_twi_tx(&twi_dist_pcf8563, I2C_PCF8563_SLAVE_ADDR, &W_reg, 1,
true);
if (NRF_SUCCESS
!= ret)
{
printf("Error 1\r\n");
return 0;
}
nrf_delay_ms(5);
ret =
nrf_drv_twi_rx(&twi_dist_pcf8563, I2C_PCF8563_SLAVE_ADDR, &W_data, 1);
if (NRF_SUCCESS
!= ret)
{
printf("Error 2\r\n");
return 0;
}
}while (0);
nrf_delay_ms(5);
return W_data;
}
//======================================================================================
void PCF8563_writeMulti(uint8_t W_reg, uint8_t const * src,
uint8_t count)
{
ret_code_t ret;
do{
uint8_t buffer[1
+ count]; /* index + data */
buffer[0] =
(uint8_t)W_reg;
memcpy(buffer +
1, src, count);
ret =
nrf_drv_twi_tx(&twi_dist_pcf8563, I2C_PCF8563_SLAVE_ADDR, buffer, count +
1, false);
} while (0);
nrf_delay_ms(5);
}
//======================================================================================
void
PCF8563_readMulti(uint8_t W_reg, uint8_t * dst, uint8_t count)
{
ret_code_t
ret;
do
{
ret =
nrf_drv_twi_tx(&twi_dist_pcf8563, I2C_PCF8563_SLAVE_ADDR, &W_reg, 1,
true);
if (NRF_SUCCESS
!= ret)
{
//printf("Return with Error \r\n");
break;
}
nrf_delay_ms(5);
ret =
nrf_drv_twi_rx(&twi_dist_pcf8563, I2C_PCF8563_SLAVE_ADDR, dst, count);
if (NRF_SUCCESS != ret)
{
printf("Return with Error \r\n");
break;
}
}while (0);
nrf_delay_ms(5);
}
//======================================================================================
void Initialize_PCF8563(void){
PCF8563_writeReg(PCF8563_CTRL_STATUS_REG1,PCF8563_START_COUNTING);
//PCF8563_writeReg(0x0D,0x83);
}
//======================================================================================
void PCF8563_set_datetime(date_time_t *dt) {
PCF8563_writeReg(PCF8563_SECONDS_REG,bin2bcd(dt->seconds));
PCF8563_writeReg(PCF8563_MINUTES_REG,bin2bcd(dt->minutes));
PCF8563_writeReg(PCF8563_HOURS_REG,bin2bcd(dt->hours));
PCF8563_writeReg(PCF8563_DAY_REG,bin2bcd(dt->day));
PCF8563_writeReg(PCF8563_WEEK_REG,dt->weekday);
PCF8563_writeReg(PCF8563_MONTH_REG,bin2bcd(dt->month));
PCF8563_writeReg(PCF8563_WEEK_REG,bin2bcd(dt->year));
}
//======================================================================================
void PCF8563_read_datetime(date_time_t *dt)
{
unsigned
char LCu_Array[7]={0};
PCF8563_readMulti(PCF8563_SECONDS_REG,LCu_Array,7);
dt->seconds
= bcd2bin(LCu_Array[0]&0x7F);
dt->minutes
= bcd2bin(LCu_Array[1]&0x7F);
dt->hours = bcd2bin(LCu_Array[2] & 0x3F);
dt->day = bcd2bin(LCu_Array[3] & 0x3F);
dt->month = bcd2bin(LCu_Array[5] & 0x1F);
dt->weekday
= LCu_Array[4] & 0x07;
dt->year = bcd2bin(LCu_Array[6]);
}
//======================================================================================
File Name : PCF8563.h
#ifndef PCF8563_H__
#define PCF8563_H__
#include "nordic_common.h"
#include "nrf_drv_config.h"
#include "app_error.h"
typedef struct
{
uint8_t seconds; //
0 to 59
uint8_t minutes; //
0 to 59
uint8_t hours; //
0 to 23 (24-hour time)
uint8_t day; //
1 to 31
uint8_t weekday; //
0 = Sunday, 1 = Monday, etc.
uint8_t month; //
1 to 12
uint8_t year; //
00 to 99
}date_time_t;
#define
I2C_PCF8563_SLAVE_ADDR 0x51
// registers //
#define PCF8563_CONTROL1
0x00 //control/status 1
#define PCF8563_CONTROL2
0x01 //control/status 2
#define PCF8563_CLKOUT
0x0D //CLKOUT control
#define PCF8563_TCONTROL
0x0E //timer control
#define PCF8563_TIMER
0x0F //timer countdown value
#define PCF8563_SECONDS
0x02 //0..59 BCD (bit7 is VL)
#define PCF8563_MINUTES
0x03 //0..59 BCD
#define PCF8563_HOURS
0x04 //0..23 bcd
#define PCF8563_DAYS
0x05 //1..31 bcd
#define PCF8563_WEEKDAY
0x06 //0..6
#define PCF8563_MONTHS
0x07 //0..12 (bit7 is Century,
leave clear for 20xx)
#define PCF8563_YEARS
0x08 //0..99 bcd
#define PCF8563_MINUTE_ALARM
0x09 //0..59 BCD
#define PCF8563_HOUR_ALARM
0x0A //0..23 BCD
#define PCF8563_DAY_ALARM
0x0B //0..31 BCD
#define PCF8563_WEEKDAY_ALARM 0x0C //0..6
// Register addresses
#define PCF8563_CTRL_STATUS_REG1 0x00
#define PCF8563_CTRL_STATUS_REG2 0x01
#define PCF8563_SECONDS_REG 0x02
#define PCF8563_MINUTES_REG 0x03
#define PCF8563_HOURS_REG 0x04
#define PCF8563_DAY_REG 0x05
#define PCF8563_WEEK_REG 0x06
#define PCF8563_MONTH_REG 0x07
#define PCF8563_YEAR_REG 0x08
#define PCF8563_ALARM_MINS_REG 0x09
#define PCF8563_ALARM_HOURS_REG 0x0A
#define PCF8563_ALARM_DAY_REG 0x0B
#define PCF8563_ALARM_WEEKDAY_REG 0x0C
#define PCF8563_CTRL_CLKOUT_REG 0x0D
#define PCF8563_CTRL_TIMER_REG 0x0E
#define PCF8563_TIMER_REG 0x0F
// Commands for the Control/Status register.
#define PCF8563_START_COUNTING 0x08
#define PCF8563_STOP_COUNTING 0x28
//************************************* for Set_Alarm()
#define PCF8563_Alarm_off 0x00
#define PCF8563_M_Mode 0x01
#define PCF8563_MH_Mode 0x04
#define PCF8563_MHW_Mode 0x07
#define PCF8563_MHD_Mode 0x0B
//************************************* for config_CLKOUT()
#define PCF8563_CLKOUT_off 0x00
#define PCF8563_CLKOUT_32KHz 0x80
#define PCF8563_CLKOUT_1KHz 0x81
#define PCF8563_CLKOUT_32Hz 0x82
#define PCF8563_CLKOUT_1Hz 0x83
//************************************* for config_PCF8563_Timer()
#define PCF8563_Timer_off 0x00
#define PCF8563_Timer_4KHz 0x80
#define PCF8563_Timer_64Hz 0x81
#define PCF8563_Timer_1Hz 0x82
#define PCF8563_Timer_1_60Hz 0x83
//************************************* for config_PCF8563_Interrupt()
#define Alarm_Interrupt_Enable 0x01
#define Timer_Interrupt_Enable 0x02
#define A_T_Interrupt_Enable 0x03
#define Timer_INT_Pulse_on 0x10
#define Timer_INT_Pulse_off 0x00
uint8_t bin2bcd(uint8_t binary_value) ;
uint8_t bcd2bin(uint8_t bcd_value) ;
void PCF8563_writeReg(uint8_t W_reg, uint8_t value);
uint8_t PCF8563_readReg(uint8_t W_reg);
void PCF8563_writeMulti(uint8_t W_reg, uint8_t const * src,
uint8_t count);
void PCF8563_readMulti(uint8_t W_reg, uint8_t * dst, uint8_t
count);
void Initialize_PCF8563(void);
void PCF8563_set_datetime(date_time_t *dt);
void PCF8563_read_datetime(date_time_t *dt) ;
#endif /* PCF8563_H_ */
No comments:
Post a Comment