2022-05-30 14:33:10 +00:00
# include "drivers/pcf85063a/pcf85063a.hpp"
# include "micropython/modules/util.hpp"
# include <string>
# include <cstring>
using namespace pimoroni ;
extern " C " {
# include "pcf85063a.h"
# include "pimoroni_i2c.h"
/***** Variables Struct *****/
typedef struct _pcf85063a_PCF85063A_obj_t {
mp_obj_base_t base ;
PCF85063A * breakout ;
_PimoroniI2C_obj_t * i2c ;
} pcf85063a_PCF85063A_obj_t ;
/***** Constructor *****/
mp_obj_t PCF85063A_make_new ( const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * all_args ) {
pcf85063a_PCF85063A_obj_t * self = nullptr ;
enum { ARG_i2c , ARG_interrupt } ;
static const mp_arg_t allowed_args [ ] = {
{ MP_QSTR_i2c , MP_ARG_OBJ , { . u_obj = nullptr } } ,
{ MP_QSTR_interrupt , MP_ARG_INT , { . u_int = PIN_UNUSED } } ,
} ;
// Parse args.
mp_arg_val_t args [ MP_ARRAY_SIZE ( allowed_args ) ] ;
mp_arg_parse_all_kw_array ( n_args , n_kw , all_args , MP_ARRAY_SIZE ( allowed_args ) , allowed_args , args ) ;
2025-03-24 11:50:45 +00:00
self = mp_obj_malloc ( pcf85063a_PCF85063A_obj_t , & pcf85063a_PCF85063A_type ) ;
2022-05-30 14:33:10 +00:00
self - > i2c = PimoroniI2C_from_machine_i2c_or_native ( args [ ARG_i2c ] . u_obj ) ;
self - > breakout = m_new_class ( PCF85063A , ( pimoroni : : I2C * ) ( self - > i2c - > i2c ) , args [ ARG_interrupt ] . u_int ) ;
self - > breakout - > init ( ) ;
return MP_OBJ_FROM_PTR ( self ) ;
}
mp_obj_t PCF85063A_reset ( mp_obj_t self_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
self - > breakout - > reset ( ) ;
return mp_const_none ;
}
2022-06-13 17:36:49 +00:00
mp_obj_t PCF85063A_datetime ( size_t n_args , const mp_obj_t * args ) {
2022-05-30 14:33:10 +00:00
enum { ARG_self , ARG_time } ;
2022-06-13 17:36:49 +00:00
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( args [ ARG_self ] , pcf85063a_PCF85063A_obj_t ) ;
2022-05-30 14:33:10 +00:00
2022-06-13 17:36:49 +00:00
if ( n_args = = 1 ) {
2022-05-30 14:33:10 +00:00
datetime_t t = self - > breakout - > get_datetime ( ) ;
// Return the date
mp_obj_t tuple [ 7 ] ;
tuple [ 0 ] = mp_obj_new_int ( t . year ) ;
tuple [ 1 ] = mp_obj_new_int ( t . month ) ;
tuple [ 2 ] = mp_obj_new_int ( t . day ) ;
tuple [ 3 ] = mp_obj_new_int ( t . hour ) ;
tuple [ 4 ] = mp_obj_new_int ( t . min ) ;
tuple [ 5 ] = mp_obj_new_int ( t . sec ) ;
tuple [ 6 ] = mp_obj_new_int ( ( t . dotw + 6 ) % 7 ) ;
return mp_obj_new_tuple ( 7 , tuple ) ;
}
else {
// Provide a new date
2022-06-13 17:36:49 +00:00
const mp_obj_t object = args [ ARG_time ] ;
2022-05-30 14:33:10 +00:00
size_t length = 0 ;
mp_obj_t * items = nullptr ;
if ( mp_obj_is_type ( object , & mp_type_list ) ) {
mp_obj_list_t * list = MP_OBJ_TO_PTR2 ( object , mp_obj_list_t ) ;
length = list - > len ;
items = list - > items ;
}
else if ( mp_obj_is_type ( object , & mp_type_tuple ) ) {
mp_obj_tuple_t * tuple = MP_OBJ_TO_PTR2 ( object , mp_obj_tuple_t ) ;
length = tuple - > len ;
items = tuple - > items ;
}
2025-03-18 17:33:11 +00:00
if ( items = = nullptr ) mp_raise_TypeError ( MP_ERROR_TEXT ( " cannot convert object to a list or tuple of integers " ) ) ;
if ( length < 7 | | length > 8 ) mp_raise_TypeError ( MP_ERROR_TEXT ( " list or tuple must contain integers in the form (year, month, mday, hour, minute, second, weekday) " ) ) ;
2022-06-13 17:36:49 +00:00
int year = mp_obj_get_int ( items [ 0 ] ) ;
int month = mp_obj_get_int ( items [ 1 ] ) ;
int day = mp_obj_get_int ( items [ 2 ] ) ;
int hour = mp_obj_get_int ( items [ 3 ] ) ;
int minute = mp_obj_get_int ( items [ 4 ] ) ;
int second = mp_obj_get_int ( items [ 5 ] ) ;
int dotw = mp_obj_get_int ( items [ 6 ] ) ;
2025-03-18 17:33:11 +00:00
if ( year < 2000 | | year > 2099 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " year out of range. Expected 2000 to 2099 " ) ) ;
if ( month < 1 | | month > 12 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " month out of range. Expected 1 to 12 " ) ) ;
if ( day < 1 | | day > 31 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " day out of range. Expected 1 to 31 " ) ) ;
if ( hour < 0 | | hour > 23 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " hour out of range. Expected 0 to 23 " ) ) ;
if ( minute < 0 | | minute > 59 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " minute out of range. Expected 0 to 59 " ) ) ;
if ( second < 0 | | second > 59 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " second out of range. Expected 0 to 59 " ) ) ;
if ( dotw < 0 | | dotw > 6 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " dotw out of range. Expected 0 to 6 " ) ) ;
2022-06-13 17:36:49 +00:00
datetime_t t ;
t . year = year ;
t . month = month ;
t . day = day ;
t . hour = hour ;
t . min = minute ;
t . sec = second ;
t . dotw = ( dotw + 1 ) % 7 ;
self - > breakout - > set_datetime ( & t ) ;
2022-05-30 14:33:10 +00:00
}
return mp_const_none ;
}
mp_obj_t PCF85063A_set_alarm ( size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
enum { ARG_self , ARG_second , ARG_minute , ARG_hour , ARG_day } ;
static const mp_arg_t allowed_args [ ] = {
{ MP_QSTR_ , MP_ARG_REQUIRED | MP_ARG_OBJ } ,
{ MP_QSTR_second , MP_ARG_INT , { . u_int = PCF85063A : : PARAM_UNUSED } } ,
{ MP_QSTR_minute , MP_ARG_INT , { . u_int = PCF85063A : : PARAM_UNUSED } } ,
{ MP_QSTR_hour , MP_ARG_INT , { . u_int = PCF85063A : : PARAM_UNUSED } } ,
{ MP_QSTR_day , MP_ARG_INT , { . u_int = PCF85063A : : PARAM_UNUSED } } ,
} ;
mp_arg_val_t args [ MP_ARRAY_SIZE ( allowed_args ) ] ;
mp_arg_parse_all ( n_args , pos_args , kw_args , MP_ARRAY_SIZE ( allowed_args ) , allowed_args , args ) ;
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( args [ ARG_self ] . u_obj , pcf85063a_PCF85063A_obj_t ) ;
int second = args [ ARG_second ] . u_int ;
int minute = args [ ARG_minute ] . u_int ;
int hour = args [ ARG_hour ] . u_int ;
int day = args [ ARG_day ] . u_int ;
if ( second ! = PCF85063A : : PARAM_UNUSED & & ( second < 0 | | second > 59 ) )
2025-03-18 17:33:11 +00:00
mp_raise_ValueError ( MP_ERROR_TEXT ( " second out of range. Expected 0 to 59 " ) ) ;
2022-06-13 17:36:49 +00:00
if ( minute ! = PCF85063A : : PARAM_UNUSED & & ( minute < 0 | | minute > 59 ) )
2025-03-18 17:33:11 +00:00
mp_raise_ValueError ( MP_ERROR_TEXT ( " minute out of range. Expected 0 to 59 " ) ) ;
2022-06-13 17:36:49 +00:00
if ( hour ! = PCF85063A : : PARAM_UNUSED & & ( hour < 0 | | hour > 23 ) )
2025-03-18 17:33:11 +00:00
mp_raise_ValueError ( MP_ERROR_TEXT ( " hour out of range. Expected 0 to 23 " ) ) ;
2022-06-13 17:36:49 +00:00
if ( day ! = PCF85063A : : PARAM_UNUSED & & ( day < 1 | | day > 31 ) )
2025-03-18 17:33:11 +00:00
mp_raise_ValueError ( MP_ERROR_TEXT ( " date out of range. Expected 1 to 31 " ) ) ;
2022-06-13 17:36:49 +00:00
self - > breakout - > set_alarm ( second , minute , hour , day ) ;
2022-05-30 14:33:10 +00:00
return mp_const_none ;
}
mp_obj_t PCF85063A_set_weekday_alarm ( size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
enum { ARG_self , ARG_second , ARG_minute , ARG_hour , ARG_dotw } ;
static const mp_arg_t allowed_args [ ] = {
{ MP_QSTR_ , MP_ARG_REQUIRED | MP_ARG_OBJ } ,
{ MP_QSTR_second , MP_ARG_INT , { . u_int = PCF85063A : : PARAM_UNUSED } } ,
{ MP_QSTR_minute , MP_ARG_INT , { . u_int = PCF85063A : : PARAM_UNUSED } } ,
{ MP_QSTR_hour , MP_ARG_INT , { . u_int = PCF85063A : : PARAM_UNUSED } } ,
{ MP_QSTR_dotw , MP_ARG_INT , { . u_int = PCF85063A : : PARAM_UNUSED } } ,
} ;
mp_arg_val_t args [ MP_ARRAY_SIZE ( allowed_args ) ] ;
mp_arg_parse_all ( n_args , pos_args , kw_args , MP_ARRAY_SIZE ( allowed_args ) , allowed_args , args ) ;
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( args [ ARG_self ] . u_obj , pcf85063a_PCF85063A_obj_t ) ;
int second = args [ ARG_second ] . u_int ;
int minute = args [ ARG_minute ] . u_int ;
int hour = args [ ARG_hour ] . u_int ;
int dotw = args [ ARG_dotw ] . u_int ;
if ( second ! = PCF85063A : : PARAM_UNUSED & & ( second < 0 | | second > 59 ) )
2025-03-18 17:33:11 +00:00
mp_raise_ValueError ( MP_ERROR_TEXT ( " second out of range. Expected 0 to 59 " ) ) ;
2022-06-13 17:36:49 +00:00
if ( minute ! = PCF85063A : : PARAM_UNUSED & & ( minute < 0 | | minute > 59 ) )
2025-03-18 17:33:11 +00:00
mp_raise_ValueError ( MP_ERROR_TEXT ( " minute out of range. Expected 0 to 59 " ) ) ;
2022-06-13 17:36:49 +00:00
if ( hour ! = PCF85063A : : PARAM_UNUSED & & ( hour < 0 | | hour > 23 ) )
2025-03-18 17:33:11 +00:00
mp_raise_ValueError ( MP_ERROR_TEXT ( " hour out of range. Expected 0 to 23 " ) ) ;
2022-06-13 17:36:49 +00:00
if ( dotw ! = PCF85063A : : PARAM_UNUSED & & ( dotw < 0 | | dotw > 6 ) )
2025-03-18 17:33:11 +00:00
mp_raise_ValueError ( MP_ERROR_TEXT ( " dotw out of range. Expected 0 to 6 " ) ) ;
2022-06-13 17:36:49 +00:00
self - > breakout - > set_weekday_alarm ( second , minute , hour , ( PCF85063A : : DayOfWeek ) dotw ) ;
2022-05-30 14:33:10 +00:00
return mp_const_none ;
}
2022-06-13 17:36:49 +00:00
mp_obj_t PCF85063A_enable_alarm_interrupt ( mp_obj_t self_in , mp_obj_t enable_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
2022-05-30 14:33:10 +00:00
2022-06-13 17:36:49 +00:00
self - > breakout - > enable_alarm_interrupt ( enable_in = = mp_const_true ) ;
2022-05-30 14:33:10 +00:00
return mp_const_none ;
}
mp_obj_t PCF85063A_read_alarm_flag ( mp_obj_t self_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
return mp_obj_new_bool ( self - > breakout - > read_alarm_flag ( ) ) ;
}
mp_obj_t PCF85063A_clear_alarm_flag ( mp_obj_t self_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
self - > breakout - > clear_alarm_flag ( ) ;
return mp_const_none ;
}
mp_obj_t PCF85063A_unset_alarm ( mp_obj_t self_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
self - > breakout - > unset_alarm ( ) ;
return mp_const_none ;
}
mp_obj_t PCF85063A_set_timer ( size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
enum { ARG_self , ARG_ticks , ARG_ttp } ;
static const mp_arg_t allowed_args [ ] = {
{ MP_QSTR_ , MP_ARG_REQUIRED | MP_ARG_OBJ } ,
{ MP_QSTR_ticks , MP_ARG_REQUIRED | MP_ARG_INT } ,
{ MP_QSTR_ttp , MP_ARG_INT , { . u_int = PCF85063A : : TIMER_TICK_1HZ } } ,
} ;
mp_arg_val_t args [ MP_ARRAY_SIZE ( allowed_args ) ] ;
mp_arg_parse_all ( n_args , pos_args , kw_args , MP_ARRAY_SIZE ( allowed_args ) , allowed_args , args ) ;
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( args [ ARG_self ] . u_obj , pcf85063a_PCF85063A_obj_t ) ;
int ticks = args [ ARG_ticks ] . u_int ;
int ttp = args [ ARG_ttp ] . u_int ;
2025-03-18 17:33:11 +00:00
if ( ticks < 0 | | ticks > 255 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " ticks out of range. Expected 0 to 255 " ) ) ;
if ( ttp < 0 | | ttp > 3 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " ttp out of range. Expected 0 to 3 " ) ) ;
2022-06-13 17:36:49 +00:00
self - > breakout - > set_timer ( ticks , ( PCF85063A : : TimerTickPeriod ) ttp ) ;
2022-05-30 14:33:10 +00:00
return mp_const_none ;
}
mp_obj_t PCF85063A_enable_timer_interrupt ( size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
enum { ARG_self , ARG_enable , ARG_flag_only } ;
static const mp_arg_t allowed_args [ ] = {
{ MP_QSTR_ , MP_ARG_REQUIRED | MP_ARG_OBJ } ,
{ MP_QSTR_enable , MP_ARG_REQUIRED | MP_ARG_BOOL } ,
{ MP_QSTR_flag_only , MP_ARG_BOOL , { . u_bool = false } } ,
} ;
mp_arg_val_t args [ MP_ARRAY_SIZE ( allowed_args ) ] ;
mp_arg_parse_all ( n_args , pos_args , kw_args , MP_ARRAY_SIZE ( allowed_args ) , allowed_args , args ) ;
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( args [ ARG_self ] . u_obj , pcf85063a_PCF85063A_obj_t ) ;
bool enable = args [ ARG_enable ] . u_bool ;
bool flag_only = args [ ARG_flag_only ] . u_bool ;
self - > breakout - > enable_timer_interrupt ( enable , flag_only ) ;
return mp_const_none ;
}
mp_obj_t PCF85063A_read_timer_flag ( mp_obj_t self_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
return mp_obj_new_bool ( self - > breakout - > read_timer_flag ( ) ) ;
}
mp_obj_t PCF85063A_clear_timer_flag ( mp_obj_t self_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
self - > breakout - > clear_timer_flag ( ) ;
return mp_const_none ;
}
mp_obj_t PCF85063A_unset_timer ( mp_obj_t self_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
self - > breakout - > unset_timer ( ) ;
return mp_const_none ;
}
2022-06-13 17:36:49 +00:00
mp_obj_t PCF85063A_set_clock_output ( mp_obj_t self_in , mp_obj_t co_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
2022-05-30 14:33:10 +00:00
2022-06-13 17:36:49 +00:00
int co = mp_obj_get_int ( co_in ) & 7 ; // Clamp to 0-7
2022-05-30 14:33:10 +00:00
2022-06-13 17:36:49 +00:00
self - > breakout - > set_clock_output ( ( PCF85063A : : ClockOut ) co ) ;
2022-05-30 14:33:10 +00:00
return mp_const_none ;
}
2022-06-27 16:23:07 +00:00
mp_obj_t PCF85063A_set_byte ( mp_obj_t self_in , mp_obj_t v ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
int val = mp_obj_get_int ( v ) ;
2025-03-18 17:33:11 +00:00
if ( val < 0 | | val > 255 ) mp_raise_ValueError ( MP_ERROR_TEXT ( " out of range. Expected 0 to 255 " ) ) ;
2022-06-27 16:23:07 +00:00
self - > breakout - > set_byte ( ( uint8_t ) val ) ;
return mp_const_none ;
}
mp_obj_t PCF85063A_get_byte ( mp_obj_t self_in ) {
pcf85063a_PCF85063A_obj_t * self = MP_OBJ_TO_PTR2 ( self_in , pcf85063a_PCF85063A_obj_t ) ;
return mp_obj_new_int ( self - > breakout - > get_byte ( ) ) ;
}
2022-05-30 14:33:10 +00:00
}