00001
00005 #include <pic24_all.h>
00006 #include "pyToC.h"
00007 #include "pyFuncsInC.h"
00008 #include <pps.h>
00009 #include <stdio.h>
00010
00011 #undef __FILE_ID__
00012 #define __FILE_ID__ 0x70
00013
00015
00016
00021 static PmReturn_t
00022 putPyClassInt(pPmFrame_t *ppframe, int32_t i32_val)
00023 {
00024 PmReturn_t retval = PM_RET_OK;
00025
00026 pPmObj_t ppo_self;
00027 pPmObj_t ppo_attrs;
00028 pPmObj_t ppo_int;
00029
00030
00031
00032
00033 ppo_self = NATIVE_GET_LOCAL(0);
00034 EXCEPTION_UNLESS(OBJ_GET_TYPE(ppo_self) == OBJ_TYPE_CLI, PM_RET_EX_TYPE,
00035 "Argument 0 must be an class instance");
00036 ppo_attrs = (pPmObj_t)((pPmInstance_t)ppo_self)->cli_attrs;
00037 PM_CHECK_FUNCTION( int_new(i32_val, &ppo_int) );
00038 PM_CHECK_FUNCTION( dict_setItem(ppo_attrs, PM_NONE, ppo_int) );
00039
00040 return retval;
00041 }
00042
00048 static PmReturn_t
00049 getPyClassInt(pPmFrame_t *ppframe, int32_t* pi32_val)
00050 {
00051 PmReturn_t retval = PM_RET_OK;
00052 pPmObj_t ppo_self;
00053 pPmObj_t ppo_attrs;
00054 pPmObj_t ppo_int;
00055
00056
00057
00058
00059 ppo_self = NATIVE_GET_LOCAL(0);
00060 EXCEPTION_UNLESS(OBJ_GET_TYPE(ppo_self) == OBJ_TYPE_CLI, PM_RET_EX_TYPE,
00061 "Argument 0 must be an class instance");
00062 ppo_attrs = (pPmObj_t) ((pPmInstance_t) ppo_self)->cli_attrs;
00063 PM_CHECK_FUNCTION( dict_getItem(ppo_attrs, PM_NONE, &ppo_int) );
00064 PM_CHECK_FUNCTION( getInt32(ppo_int, pi32_val) );
00065
00066 return retval;
00067 }
00069
00073 #define OC_CONTROL_OFFSET 3
00074
00075 PmReturn_t
00076 configDigitalPinPy(pPmFrame_t *ppframe)
00077 {
00078 PmReturn_t retval = PM_RET_OK;
00079 uint16_t u16_port;
00080 uint16_t u16_pin;
00081 bool_t b_isInput;
00082 bool_t b_isOpenDrain = C_FALSE;
00083 int16_t i16_pullDir = 0;
00084
00085
00086 EXCEPTION_UNLESS(NATIVE_GET_NUM_ARGS() >= 4, PM_RET_EX_TYPE,
00087 "Expected at least 4 arguments, but received %u.",
00088 (uint16_t) NATIVE_GET_NUM_ARGS());
00089 GET_UINT16_ARG(1, &u16_port);
00090 GET_UINT16_ARG(2, &u16_pin);
00091 GET_BOOL_ARG(3, &b_isInput);
00092 if (NATIVE_GET_NUM_ARGS() >= 5)
00093 GET_BOOL_ARG(4, &b_isOpenDrain);
00094 if (NATIVE_GET_NUM_ARGS() >= 6)
00095 GET_INT16_ARG(5, &i16_pullDir);
00096
00097
00098 PM_CHECK_FUNCTION( putPyClassInt(ppframe,
00099 (((int32_t) u16_port) << 16) | u16_pin) );
00100
00101 PM_CHECK_FUNCTION( configDigitalPin(u16_port, u16_pin, b_isInput,
00102 b_isOpenDrain, i16_pullDir) );
00103 NATIVE_SET_TOS(PM_NONE);
00104
00105 return retval;
00106 }
00107
00116 static PmReturn_t
00117 getPyPortPin(pPmFrame_t *ppframe, uint16_t* pu16_port, uint16_t* pu16_pin)
00118 {
00119 PmReturn_t retval = PM_RET_OK;
00120 int32_t i32_portPin;
00121
00122 PM_CHECK_FUNCTION( getPyClassInt(ppframe, &i32_portPin) );
00123 *pu16_port = i32_portPin >> 16;
00124 *pu16_pin = i32_portPin & 0x00FF;
00125
00126 return retval;
00127 }
00128
00129 PmReturn_t
00130 setDigitalPinPy(pPmFrame_t *ppframe)
00131 {
00132 PmReturn_t retval = PM_RET_OK;
00133 uint16_t u16_port;
00134 uint16_t u16_pin;
00135 bool_t b_isHigh;
00136
00137
00138 CHECK_NUM_ARGS(2);
00139 PM_CHECK_FUNCTION( getPyPortPin(ppframe, &u16_port, &u16_pin) );
00140 GET_BOOL_ARG(1, &b_isHigh);
00141
00142
00143 PM_CHECK_FUNCTION( setDigitalPin(u16_port, u16_pin, b_isHigh) );
00144
00145
00146 NATIVE_SET_TOS(PM_NONE);
00147 return retval;
00148 }
00149
00150 PmReturn_t
00151 readDigitalPinPy(pPmFrame_t *ppframe)
00152 {
00153 PmReturn_t retval = PM_RET_OK;
00154 uint16_t u16_port;
00155 uint16_t u16_pin;
00156 bool_t b_isHigh;
00157
00158
00159 CHECK_NUM_ARGS(1);
00160 PM_CHECK_FUNCTION( getPyPortPin(ppframe, &u16_port, &u16_pin) );
00161
00162
00163 PM_CHECK_FUNCTION( readDigitalPin(u16_port, u16_pin, &b_isHigh) );
00164
00165
00166 NATIVE_SET_TOS(b_isHigh ? PM_TRUE : PM_FALSE);
00167 return retval;
00168 }
00169
00170 PmReturn_t
00171 readDigitalValuePy(pPmFrame_t *ppframe)
00172 {
00173 PmReturn_t retval = PM_RET_OK;
00174 uint16_t u16_port;
00175 uint16_t u16_pin;
00176 bool_t b_isHigh;
00177 bool_t b_isInput;
00178
00179
00180 CHECK_NUM_ARGS(1);
00181 PM_CHECK_FUNCTION( getPyPortPin(ppframe, &u16_port, &u16_pin) );
00182
00183
00184 PM_CHECK_FUNCTION( getPinIsInput(u16_port, u16_pin, &b_isInput) );
00185
00186 if (b_isInput) {
00187 PM_CHECK_FUNCTION( readDigitalPin(u16_port, u16_pin, &b_isHigh) );
00188 } else {
00189 PM_CHECK_FUNCTION( readDigitalLatch(u16_port, u16_pin, &b_isHigh) );
00190 }
00191
00192
00193 NATIVE_SET_TOS(b_isHigh ? PM_TRUE : PM_FALSE);
00194 return retval;
00195 }
00196
00197 PmReturn_t
00198 readDigitalLatchPy(pPmFrame_t *ppframe)
00199 {
00200 PmReturn_t retval = PM_RET_OK;
00201 uint16_t u16_port;
00202 uint16_t u16_pin;
00203 bool_t b_isHigh;
00204
00205
00206 CHECK_NUM_ARGS(1);
00207 PM_CHECK_FUNCTION( getPyPortPin(ppframe, &u16_port, &u16_pin) );
00208
00209
00210 PM_CHECK_FUNCTION( readDigitalLatch(u16_port, u16_pin, &b_isHigh) );
00211
00212
00213 NATIVE_SET_TOS(b_isHigh ? PM_TRUE : PM_FALSE);
00214 return retval;
00215 }
00216
00217 PmReturn_t
00218 configAnalogPinPy(pPmFrame_t *ppframe)
00219 {
00220 PmReturn_t retval = PM_RET_OK;
00221 uint16_t u16_analogPin;
00222
00223
00224 CHECK_NUM_ARGS(2);
00225 GET_UINT16_ARG(1, &u16_analogPin);
00226
00227
00228 PM_CHECK_FUNCTION( putPyClassInt(ppframe, u16_analogPin) );
00229
00230 PM_CHECK_FUNCTION( configAnalogPin(u16_analogPin) );
00231 NATIVE_SET_TOS(PM_NONE);
00232
00233 return retval;
00234 }
00235
00241 static PmReturn_t
00242 readAnalogCode(pPmFrame_t *ppframe, uint16_t* pu16_analogCode)
00243 {
00244 PmReturn_t retval = PM_RET_OK;
00245 int32_t i32_analogPin;
00246 uint16_t u16_analogPin;
00247
00248
00249 CHECK_NUM_ARGS(1);
00250 PM_CHECK_FUNCTION( getPyClassInt(ppframe, &i32_analogPin) );
00251 ASSERT( (i32_analogPin >= 0) && (i32_analogPin < 32) );
00252 u16_analogPin = i32_analogPin;
00253
00254
00255 configADC1_ManualCH0(ADC_CH0_POS_SAMPLEA_AN0 + u16_analogPin, 31, C_TRUE);
00256 *pu16_analogCode = convertADC1();
00257
00258 return retval;
00259 }
00260
00261 PmReturn_t
00262 readAnalogCodePy(pPmFrame_t *ppframe)
00263 {
00264 PmReturn_t retval = PM_RET_OK;
00265 uint16_t u16_analogCode;
00266 pPmObj_t ppo_analogCode;
00267
00268 PM_CHECK_FUNCTION( readAnalogCode(ppframe, &u16_analogCode) );
00269 PM_CHECK_FUNCTION( int_new(u16_analogCode, &ppo_analogCode) );
00270 NATIVE_SET_TOS(ppo_analogCode);
00271 return retval;
00272 }
00273
00274 PmReturn_t
00275 readAnalogFloatPy(pPmFrame_t *ppframe, float f_scale)
00276 {
00277 PmReturn_t retval = PM_RET_OK;
00278 uint16_t u16_analogCode;
00279 pPmObj_t ppo_analogCode;
00280
00281 PM_CHECK_FUNCTION( readAnalogCode(ppframe, &u16_analogCode) );
00282 PM_CHECK_FUNCTION( float_new(f_scale*u16_analogCode, &ppo_analogCode) );
00283 NATIVE_SET_TOS(ppo_analogCode);
00284 return retval;
00285 }
00286
00287 PmReturn_t
00288 configPwmPy(pPmFrame_t *ppframe)
00289 {
00290 PmReturn_t retval = PM_RET_OK;
00291 uint32_t u32_freq;
00292 bool_t b_isTimer2;
00293 uint16_t u16_oc;
00294 int16_t i16_ocPin;
00295 uint16_t u16_pr;
00296
00297
00298 CHECK_NUM_ARGS(5);
00299 GET_UINT32_ARG(1, &u32_freq);
00300 GET_BOOL_ARG(2, &b_isTimer2);
00301 GET_UINT16_ARG(3, &u16_oc);
00302 GET_INT16_ARG(4, &i16_ocPin);
00303
00304 PM_CHECK_FUNCTION( configPwm(u32_freq, b_isTimer2, u16_oc, i16_ocPin) );
00305
00306
00307 u16_pr = b_isTimer2 ? PR2 : PR3;
00308 PM_CHECK_FUNCTION( putPyClassInt(ppframe, u16_oc | (((uint32_t) u16_pr) << 16)) );
00309 NATIVE_SET_TOS(PM_NONE);
00310 return retval;
00311 }
00312
00317 #define OC_REG(u16_reg, u16_n) \
00318 ((volatile uint16_t*) &u16_reg)[(u16_n - 1)*OC_CONTROL_OFFSET]
00319
00320 PmReturn_t
00321 configPwm(uint32_t u32_freq, bool_t b_isTimer2, uint16_t u16_oc,
00322 int16_t i16_ocPin)
00323 {
00324 PmReturn_t retval = PM_RET_OK;
00325 uint32_t u32_counts;
00326 uint16_t u16_prescale;
00327 uint16_t u16_t2con;
00328 uint16_t u16_counts;
00329
00330 EXCEPTION_UNLESS((u16_oc < NUM_OC_MODS) && (u16_oc > 0), PM_RET_EX_VAL,
00331 "Requested OC module %d does not exist", u16_oc);
00332
00333
00334 #ifdef HAS_REMAPPABLE_PINS
00335 EXCEPTION_UNLESS(i16_ocPin >= 0, PM_RET_EX_VAL,
00336 "Invalid pin RP%d.", i16_ocPin);
00337 EXCEPTION_UNLESS(digitalPinExists(PORT_B_INDEX + (i16_ocPin >> 4),
00338 i16_ocPin & 0xF), PM_RET_EX_VAL,
00339 "Invalid pin RP%d.", i16_ocPin);
00340
00341 PM_CHECK_FUNCTION(
00342 configDigitalPin(PORT_B_INDEX + (i16_ocPin >> 4),
00343 i16_ocPin & 0xF, C_FALSE, C_FALSE, 0) );
00344
00345
00346
00347
00348 ((volatile uint8_t*) &RPOR0)[i16_ocPin] = OUT_FN_PPS_OC1 + u16_oc - 1;
00349 #else
00350 EXCEPTION_UNLESS(i16_ocPin < 0, PM_RET_EX_VAL,
00351 "Remapping not possible on this device.");
00352 #endif
00353
00354
00355 OC_REG(OC1RS, u16_oc) = 0;
00356
00357
00358 EXCEPTION_UNLESS(u32_freq <= FCY, PM_RET_EX_VAL,
00359 "Frequency %ld too high", u32_freq);
00360 u32_counts = FCY/u32_freq;
00361 u16_prescale = u32_counts >> 16;
00362 EXCEPTION_UNLESS(u16_prescale <= 256, PM_RET_EX_VAL,
00363 "Frequency %ld too low", u32_freq);
00364 u16_t2con = 0;
00365 if (u16_prescale > 64)
00366 {
00367 u16_t2con = T2_PS_1_256;
00368 u16_counts = (u32_counts >> 8) - 1;
00369 } else if (u16_prescale > 8)
00370 {
00371 u16_t2con = T2_PS_1_64;
00372 u16_counts = (u32_counts >> 6) - 1;
00373 } else if (u16_prescale > 0)
00374 {
00375 u16_t2con = T2_PS_1_8;
00376 u16_counts = (u32_counts >> 3) - 1;
00377 } else {
00378 u16_t2con = T2_PS_1_1;
00379 u16_prescale = 0;
00380 u16_counts = u32_counts - 1;
00381 }
00382
00383
00384 if (b_isTimer2)
00385 {
00386 T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF
00387 | T2_32BIT_MODE_OFF
00388 | T2_SOURCE_INT
00389 | u16_t2con;
00390 TMR2 = 0;
00391 PR2 = u16_counts;
00392 OC_REG(OC1CON, u16_oc) = OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE;
00393 T2CONbits.TON = 1;
00394 } else {
00395 T3CON = T3_OFF | T3_IDLE_CON | T3_GATE_OFF
00396 | T3_SOURCE_INT
00397 | u16_t2con;
00398 PR3 = 0;
00399 PR3 = u16_counts;
00400 OC_REG(OC1CON, u16_oc) = OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE;
00401 T3CONbits.TON = 1;
00402 }
00403
00404 return retval;
00405 }
00406
00416 static PmReturn_t
00417 getPyOcPrn(pPmFrame_t *ppframe, uint16_t* pu16_oc, uint16_t* pu16_prn)
00418 {
00419 PmReturn_t retval = PM_RET_OK;
00420 int32_t i32_prnOc;
00421
00422 PM_CHECK_FUNCTION( getPyClassInt(ppframe, &i32_prnOc) );
00423 *pu16_prn = i32_prnOc >> 16;
00424 *pu16_oc = i32_prnOc & 0x00FF;
00425
00426 return retval;
00427 }
00428
00429 PmReturn_t
00430 setPwmCountsPy(pPmFrame_t *ppframe)
00431 {
00432 PmReturn_t retval = PM_RET_OK;
00433 uint16_t u16_counts;
00434 uint16_t u16_oc;
00435 uint16_t u16_prn;
00436
00437 CHECK_NUM_ARGS(2);
00438 GET_UINT16_ARG(1, &u16_counts);
00439 PM_CHECK_FUNCTION(getPyOcPrn(ppframe, &u16_oc, &u16_prn) );
00440 PM_CHECK_FUNCTION(setPwmCounts(u16_counts, u16_oc) );
00441
00442 return retval;
00443 }
00444
00445 PmReturn_t
00446 setPwmCounts(uint16_t u16_counts, uint16_t u16_oc)
00447 {
00448 PmReturn_t retval = PM_RET_OK;
00449
00450 ASSERT(u16_oc <= NUM_OC_MODS);
00451 OC_REG(OC1RS, u16_oc) = u16_counts;
00452
00453 return retval;
00454 }
00455
00456 PmReturn_t
00457 setPwmRatioPy(pPmFrame_t *ppframe)
00458 {
00459 PmReturn_t retval = PM_RET_OK;
00460 float f_ratio;
00461 uint16_t u16_oc;
00462 uint16_t u16_prn;
00463
00464 CHECK_NUM_ARGS(2);
00465 GET_FLOAT_ARG(1, &f_ratio);
00466 PM_CHECK_FUNCTION(getPyOcPrn(ppframe, &u16_oc, &u16_prn) );
00467 PM_CHECK_FUNCTION(setPwmCounts((((uint32_t) u16_prn) + 1)*f_ratio, u16_oc) );
00468
00469 return retval;
00470 }