Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement get_fattime #160

Merged
merged 19 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Makefile

*.dump
.vscode/*
.idea/*

*~*
\#*\#
Expand Down
2 changes: 1 addition & 1 deletion src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ command_func_t* const cmd_table[NUM_PRIMARY_CMDS + 1][NUM_SECONDARY_CMDS_MAX + 1
},
{ // 13 SENSORS
// 0 1 RTC_SETTIME 2 RTC_SETDIGIT 3 RTC_GETTIME
Undefined, RTC_SetTime, RTC_SetDigit, RTC_GetTime,
Undefined, RTC_CmdSetTime, RTC_SetDigit, RTC_CmdGetTime,
// 4 RTC_GETDIGIT 5 HCSR04 6 AM2302 7 BMP180
RTC_GetDigit, Unimplemented, Unimplemented, Unimplemented,
// 8 TSL2591 9 TCD1304 10 11
Expand Down
94 changes: 81 additions & 13 deletions src/helpers/rtc.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdint.h>
#include <time.h>

#include "../bus/i2c/i2c.h"
#include "../bus/uart/uart.h"
Expand All @@ -8,24 +9,69 @@
#include "light.h"
#include "rtc.h"

response_t RTC_SetTime(void) {

// This bit is used to enable the oscillator. When negated, the oscillator is disabled.
static uint8_t const oscillator_enable = 0x7F;

static uint8_t data_to_bcd(uint8_t data){
uint8_t bcd = data;

if(data >= 10){
uint8_t left = data / 10;
uint8_t right = data % 10;
bcd = (left << 4) | right;
}
return bcd;
}

static uint8_t bcd_to_data(uint8_t bcd){
uint8_t right = (0xF & bcd);
uint8_t left = (bcd >> 4) & 0xF;

left *= 10;
return left + right;
}

response_t RTC_SetTime(uint32_t const * const unix_timestamp) {

time_t timestamp = (time_t) *unix_timestamp;
struct tm *tm_info;

tm_info = gmtime(&timestamp);
uint8_t sec = tm_info->tm_sec;
uint8_t min = tm_info->tm_min;
uint8_t hours = tm_info->tm_hour;
uint8_t day = tm_info->tm_wday + 1;
uint8_t date = tm_info->tm_mday;
uint8_t month = tm_info->tm_mon + 1;
uint8_t year = tm_info->tm_year % 100; // Tm_year starts from 00 which means(1900).
// ds1307 only stores the last 2 digits.
if(sec == 60)
sec = 0;

// Default 24 hrs format.
uint8_t buffer[9];
buffer[0] = DS1307_DATA_REG_SECONDS;
buffer[1] = UART1_Read() & 0x7F; // seconds
buffer[2] = UART1_Read(); // minutes
buffer[3] = UART1_Read(); // hours
buffer[4] = UART1_Read(); // day
buffer[5] = UART1_Read(); // date
buffer[6] = UART1_Read(); // month
buffer[7] = UART1_Read(); // year
buffer[8] = UART1_Read(); // control
buffer[1] = data_to_bcd(sec) & oscillator_enable; // seconds
buffer[2] = data_to_bcd(min); // minutes
buffer[3] = data_to_bcd(hours); // hours (hrs format)
buffer[4] = data_to_bcd(day); // day
buffer[5] = data_to_bcd(date); // date
buffer[6] = data_to_bcd(month); // month
buffer[7] = data_to_bcd(year); // year
buffer[8] = 0; // control

I2C_InitializeIfNot(I2C_BAUD_RATE_100KHZ, I2C_ENABLE_INTERRUPTS);

return I2C_BulkWrite(buffer, 9, DS1307_I2C_DEVICE_ADDRESS);
}

response_t RTC_CmdSetTime(void) {
uint32_t unix_timestamp = UART1_read_u32();

response_t res = RTC_SetTime(&unix_timestamp);
return res;
}

response_t RTC_SetDigit(void) {

uint8_t buffer[2];
Expand All @@ -37,20 +83,42 @@ response_t RTC_SetDigit(void) {
return I2C_BulkWrite(buffer, 2, DS1307_I2C_DEVICE_ADDRESS);
}

response_t RTC_GetTime(void) {
response_t RTC_GetTime(uint32_t* unix_timestamp) {

uint8_t buffer[7];
struct tm tm_info;

I2C_InitializeIfNot(I2C_BAUD_RATE_100KHZ, I2C_ENABLE_INTERRUPTS);

if(I2C_BulkRead(DS1307_DATA_REG_SECONDS, DS1307_I2C_DEVICE_ADDRESS, buffer, 7) == SUCCESS) {
uint8_t i;
for (i = 0; i < sizeof(buffer); i++) UART1_Write(buffer[i]);

// Need to convert from bcd to int.
tm_info.tm_sec = bcd_to_data(buffer[0]);
tm_info.tm_min = bcd_to_data(buffer[1]);
tm_info.tm_hour = bcd_to_data(buffer[2]);
tm_info.tm_wday = bcd_to_data(buffer[3]) - 1;
tm_info.tm_mday = bcd_to_data(buffer[4]);
tm_info.tm_mon = bcd_to_data(buffer[5]) - 1;
tm_info.tm_year = 100 + bcd_to_data(buffer[6]); // 100 means for year 2000 (2000 - 1900)

tm_info.tm_sec = tm_info.tm_sec & oscillator_enable;

uint32_t timestamp = (uint32_t) mktime(&tm_info);
*unix_timestamp = timestamp;
} else return FAILED;

return SUCCESS;
}

response_t RTC_CmdGetTime(void){
uint32_t unix_timestamp;
response_t res = RTC_GetTime(&unix_timestamp);

// What if error occurs here, Returns fail.
UART1_write_u32(unix_timestamp);
return res;
}

response_t RTC_GetDigit(void) {

uint8_t buffer[1];
Expand Down
36 changes: 32 additions & 4 deletions src/helpers/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define RTC_H

#include <xc.h>
#include "../commands.h"

#define DS1307_I2C_DEVICE_ADDRESS 0x68

Expand Down Expand Up @@ -60,11 +61,26 @@ extern "C" {
* | OUT (1) | XX (2) | SQWE (1) | XX (2) | RS1:0 (2) |
*
* This method does not pass any messages over the serial back to host.
* This method decodes the unix_timestamp passed as param, converts it into RTC format and
* stores the value in RTC hardware.
*
* @Param
* const* const unix_timestamp: Time to be stored in 32 bit unix timestamp format.
*
* @return SUCCESS, FAILED
*/
response_t RTC_SetTime(void);

response_t RTC_SetTime(uint32_t const* const unix_timestamp);

/**
* @brief Stores time in RTC Hardware.
*
* @description This method reads 32 bit unix timestamp unsigned integer from the host and
* stores the value in RTC Hardware by calling RTC_SetTime function.
*
* @return SUCCESS, FAILED
*/
response_t RTC_CmdSetTime(void);

/**
* @brief Updates a single time parameter in DS1307 real-time clock
*
Expand Down Expand Up @@ -94,11 +110,23 @@ extern "C" {
*
* This method will pass 8 unsigned bytes to the host over serial and host
* will need to read all 7 bytes to complete the transaction.
*
* @param
* *unix_timestamp - Time in RTC hardware is converted to unix_timestamp and stored in the parameter
*
* @return SUCCESS, FAILED
*/
response_t RTC_GetTime(void);

response_t RTC_GetTime(uint32_t* unix_timestamp);

/**
* @Brief Fetches time from RTC Hardware in unix_timestamp format.
*
* @Description This method reads time from RTC Hardware and returns the value in unix_timestamp
* format by calling the RTC_GetTime function.
*
* @return SUCCESS, FAILED
*/
response_t RTC_CmdGetTime(void);
/**
* @brief Fetch a single time parameter from DS1307 real-time clock
*
Expand Down
30 changes: 17 additions & 13 deletions src/sdcard/fatfs/ff_time.c
Hrushi20 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,27 @@
*/

#include "ff.h"
#include <time.h>
#include <stdint.h>
#include "../../helpers/rtc.h"

DWORD get_fattime (void){

uint32_t unix_timestamp = 0;
RTC_GetTime(&unix_timestamp);
struct tm *tm_info;

time_t timestamp = (time_t) (unix_timestamp);
tm_info = gmtime(&timestamp);

static DWORD decimalToFatTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t seconds)
{
DWORD fatTime;

fatTime = (seconds >> 1);
fatTime |= ( ((DWORD)minute) << 5 );
fatTime |= ( ((DWORD)hour) << 11 );
fatTime |= ( ((DWORD)day) << 16 );
fatTime |= ( ((DWORD)month) << 21 );
fatTime |= ( ((DWORD)(year - 1980)) << 25 );
fatTime = (tm_info->tm_sec >> 1);
fatTime |= ( ((DWORD)tm_info->tm_min) << 5 );
fatTime |= ( ((DWORD)tm_info->tm_hour) << 11 );
fatTime |= ( ((DWORD)tm_info->tm_mday) << 16 );
fatTime |= ( ((DWORD)tm_info->tm_mon + 1) << 21 );
fatTime |= ( ((DWORD)(tm_info->tm_year - 80)) << 25 );

return fatTime;
}

DWORD get_fattime (void)
{
return decimalToFatTime(2018, 6, 31, 5, 10, 30);
}