plat.c

Go to the documentation of this file.
00001 /*
00002 # This file is Copyright 2006, 2007, 2009 Dean Hall.
00003 #
00004 # This file is part of the Python-on-a-Chip program.
00005 # Python-on-a-Chip is free software: you can redistribute it and/or modify
00006 # it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
00007 #
00008 # Python-on-a-Chip is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 # A copy of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
00012 # is seen in the file COPYING up one directory from this.
00013 */
00014 
00015 
00016 #undef __FILE_ID__
00017 #define __FILE_ID__ 0x51
00018 
00019 
00025 #include <stdio.h>
00026 #include <pic24_all.h>
00027 #include "pm.h"
00028 
00032 volatile uint32_t u32_ms = 0;
00033 
00035 #define ISR_PERIOD  1    // in ms
00036 
00040 void _ISR _T2Interrupt (void) {
00041     PmReturn_t retval;
00042 
00043     u32_ms++;
00044     _T2IF = 0;                 //clear the timer interrupt bit
00045     retval = pm_vmPeriodic(ISR_PERIOD * 1000);
00046     PM_REPORT_IF_ERROR(retval);
00047 }
00048 
00050 void  configTimer2(void) {
00051   // Configure the timer
00052   T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF
00053           | T2_32BIT_MODE_OFF
00054           | T2_SOURCE_INT
00055           | T2_PS_1_1;
00056   // Subtract 1 from ticks value assigned to PR2 because period is PRx + 1
00057   PR2 = msToU16Ticks(ISR_PERIOD, getTimerPrescale(T2CONbits)) - 1;
00058   TMR2  = 0;                       //clear timer2 value
00059   _T2IF = 0;                       //clear interrupt flag
00060   _T2IP = 1;                       //choose a priority
00061   _T2IE = 1;                       //enable the interrupt
00062   T2CONbits.TON = 1;               //turn on the timer
00063 }
00064 
00065 
00066 PmReturn_t plat_init(void)
00067 {
00068   configBasic(HELLO_MSG);
00069   configTimer2();
00070   
00071   return PM_RET_OK;
00072 }
00073 
00074 
00075 PmReturn_t
00076 plat_deinit(void)
00077 {
00078     // Disable timer interrupts
00079     _T2IE = 0;
00080 
00081     return PM_RET_OK;
00082 }
00083 
00084 
00085 /*
00086  * Gets a byte from the address in the designated memory space
00087  * Post-increments *paddr.
00088  */
00089 uint8_t
00090 plat_memGetByte(PmMemSpace_t memspace, uint8_t const **paddr)
00091 {
00092     uint8_t b = 0;
00093 
00094     switch (memspace)
00095     {
00096         case MEMSPACE_RAM:
00097             b = **paddr;
00098             *paddr += 1;
00099             return b;
00100 
00101         /* For now, assume a large memory model, so all program memory
00102          * can be mapped into the PSV space. */
00103         case MEMSPACE_PROG:
00104             b = **paddr;
00105             *paddr += 1;
00106             return b;
00107 
00108         case MEMSPACE_EEPROM:  // Not yet implemented.
00109         case MEMSPACE_SEEPROM:
00110         case MEMSPACE_OTHER0:
00111         case MEMSPACE_OTHER1:
00112         case MEMSPACE_OTHER2:
00113         case MEMSPACE_OTHER3:
00114         default:
00115             return 0;
00116     }
00117 }
00118 
00119 
00120 /*
00121  * UART receive char routine MUST return exactly and only the received char;
00122  * it should not translate \n to \r\n.
00123  * This is because the interactive interface uses binary transfers.
00124  */
00125 PmReturn_t
00126 plat_getByte(uint8_t *b)
00127 {
00128   PmReturn_t retval = PM_RET_OK;
00129 
00130   /* Wait for character */
00131   while (!isCharReady1()) doHeartbeat();
00132 
00133   /* Return errors for Framing error or Overrun */
00134   if (U1STAbits.PERR || U1STAbits.FERR || U1STAbits.OERR) {
00135     PM_RAISE(retval, PM_RET_EX_IO);
00136     return retval;
00137   }
00138   *b = U1RXREG;
00139 
00140   return retval;
00141 }
00142 
00143 
00144 /*
00145  * UART send char routine MUST send exactly and only the given char;
00146  * it should not translate \n to \r\n.
00147  * This is because the interactive interface uses binary transfers.
00148  */
00149 PmReturn_t
00150 plat_putByte(uint8_t b)
00151 {
00152   outChar1(b);
00153   return PM_RET_OK;
00154 }
00155 
00156 
00160 PmReturn_t
00161 plat_getMsTicks(uint32_t *r_ticks)
00162 {
00163     *r_ticks = u32_ms;
00164     return PM_RET_OK;
00165 }
00166 
00167 void
00168 plat_reportError(PmReturn_t result)
00169 {
00170 
00171 #ifdef HAVE_DEBUG_INFO
00172 #define LEN_FNLOOKUP 26
00173 #define LEN_EXNLOOKUP 17
00174 
00175     uint8_t res;
00176     pPmFrame_t pframe;
00177     pPmObj_t pstr;
00178     PmReturn_t retval;
00179     uint8_t bcindex;
00180     uint16_t bcsum;
00181     uint16_t linesum;
00182     uint16_t len_lnotab;
00183     uint8_t const *plnotab;
00184     uint16_t i;
00185 
00186     /* This table should match src/vm/fileid.txt */
00187     char const * const fnlookup[LEN_FNLOOKUP] = {
00188         "<no file>",
00189         "codeobj.c",
00190         "dict.c",
00191         "frame.c",
00192         "func.c",
00193         "global.c",
00194         "heap.c",
00195         "img.c",
00196         "int.c",
00197         "interp.c",
00198         "pmstdlib_nat.c",
00199         "list.c",
00200         "main.c",
00201         "mem.c",
00202         "module.c",
00203         "obj.c",
00204         "seglist.c",
00205         "sli.c",
00206         "strobj.c",
00207         "tuple.c",
00208         "seq.c",
00209         "pm.c",
00210         "thread.c",
00211         "float.c",
00212         "class.c",
00213         "bytearray.c",
00214     };
00215 
00216     /* This table should match src/vm/pm.h PmReturn_t */
00217     char const * const exnlookup[LEN_EXNLOOKUP] = {
00218         "Exception",
00219         "SystemExit",
00220         "IoError",
00221         "ZeroDivisionError",
00222         "AssertionError",
00223         "AttributeError",
00224         "ImportError",
00225         "IndexError",
00226         "KeyError",
00227         "MemoryError",
00228         "NameError",
00229         "SyntaxError",
00230         "SystemError",
00231         "TypeError",
00232         "ValueError",
00233         "StopIteration",
00234         "Warning",
00235     };
00236 
00237     /* Print traceback */
00238     printf("Traceback (most recent call first):\n");
00239 
00240     /* Get the top frame */
00241     pframe = gVmGlobal.pthread->pframe;
00242 
00243     /* If it's the native frame, print the native function name */
00244     if (pframe == (pPmFrame_t)&(gVmGlobal.nativeframe))
00245     {
00246 
00247         /* The last name in the names tuple of the code obj is the name */
00248         retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func->
00249                                f_co->co_names, -1, &pstr);
00250         if ((retval) != PM_RET_OK)
00251         {
00252             printf("  Unable to get native func name.\n");
00253             return;
00254         }
00255         else
00256         {
00257             printf("  %s() __NATIVE__\n", ((pPmString_t)pstr)->val);
00258         }
00259 
00260         /* Get the frame that called the native frame */
00261         pframe = (pPmFrame_t)gVmGlobal.nativeframe.nf_back;
00262     }
00263 
00264     /* Print the remaining frame stack */
00265     for (; pframe != C_NULL; pframe = pframe->fo_back)
00266     {
00267         /* The last name in the names tuple of the code obj is the name */
00268         retval = tuple_getItem((pPmObj_t)pframe->fo_func->f_co->co_names,
00269                                -1,
00270                                &pstr);
00271         if ((retval) != PM_RET_OK) break;
00272 
00273         /*
00274          * Get the line number of the current bytecode. Algorithm comes from:
00275          * http://svn.python.org/view/python/trunk/Objects/lnotab_notes.txt?view=markup
00276          */
00277         bcindex = pframe->fo_ip - pframe->fo_func->f_co->co_codeaddr;
00278         plnotab = pframe->fo_func->f_co->co_lnotab;
00279         len_lnotab = mem_getWord(MEMSPACE_PROG, &plnotab);
00280         bcsum = 0;
00281         linesum = pframe->fo_func->f_co->co_firstlineno;
00282         for (i = 0; i < len_lnotab; i += 2)
00283         {
00284             bcsum += mem_getByte(MEMSPACE_PROG, &plnotab);
00285             if (bcsum > bcindex) break;
00286             linesum += mem_getByte(MEMSPACE_PROG, &plnotab);
00287         }
00288         printf("  File \"%s\", line %d, in %s\n",
00289                ((pPmFrame_t)pframe)->fo_func->f_co->co_filename,
00290                linesum,
00291                ((pPmString_t)pstr)->val);
00292     }
00293 
00294     /* Print error */
00295     res = (uint8_t)result;
00296     if ((res > 0) && ((res - PM_RET_EX) < LEN_EXNLOOKUP))
00297     {
00298         printf("%s", exnlookup[res - PM_RET_EX]);
00299     }
00300     else
00301     {
00302         printf("Error code 0x%02X", result);
00303     }
00304     printf(" detected by ");
00305 
00306     if ((gVmGlobal.errFileId > 0) && (gVmGlobal.errFileId < LEN_FNLOOKUP))
00307     {
00308         printf("%s:", fnlookup[gVmGlobal.errFileId]);
00309     }
00310     else
00311     {
00312         printf("FileId 0x%02X line ", gVmGlobal.errFileId);
00313     }
00314     printf("%d\n", gVmGlobal.errLineNum);
00315 
00316 #else /* HAVE_DEBUG_INFO */
00317 
00318     /* Print error */
00319     printf("Error:     0x%02X\n", result);
00320     printf("  Release: 0x%02X\n", gVmGlobal.errVmRelease);
00321     printf("  FileId:  0x%02X\n", gVmGlobal.errFileId);
00322     printf("  LineNum: %d\n", gVmGlobal.errLineNum);
00323 
00324     /* Print traceback */
00325     {
00326         pPmObj_t pframe;
00327         pPmObj_t pstr;
00328         PmReturn_t retval;
00329 
00330         printf("Traceback (top first):\n");
00331 
00332         /* Get the top frame */
00333         pframe = (pPmObj_t)gVmGlobal.pthread->pframe;
00334 
00335         /* If it's the native frame, print the native function name */
00336         if (pframe == (pPmObj_t)&(gVmGlobal.nativeframe))
00337         {
00338 
00339             /* The last name in the names tuple of the code obj is the name */
00340             retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func->
00341                                    f_co->co_names, -1, &pstr);
00342             if ((retval) != PM_RET_OK)
00343             {
00344                 printf("  Unable to get native func name.\n");
00345                 return;
00346             }
00347             else
00348             {
00349                 printf("  %s() __NATIVE__\n", ((pPmString_t)pstr)->val);
00350             }
00351 
00352             /* Get the frame that called the native frame */
00353             pframe = (pPmObj_t)gVmGlobal.nativeframe.nf_back;
00354         }
00355 
00356         /* Print the remaining frame stack */
00357         for (;
00358              pframe != C_NULL;
00359              pframe = (pPmObj_t)((pPmFrame_t)pframe)->fo_back)
00360         {
00361             /* The last name in the names tuple of the code obj is the name */
00362             retval = tuple_getItem((pPmObj_t)((pPmFrame_t)pframe)->
00363                                    fo_func->f_co->co_names, -1, &pstr);
00364             if ((retval) != PM_RET_OK) break;
00365 
00366             printf("  %s()\n", ((pPmString_t)pstr)->val);
00367         }
00368         printf("  <module>.\n");
00369     }
00370 #endif /* HAVE_DEBUG_INFO */
00371 }

Generated on Mon Oct 18 07:40:46 2010 for Python-on-a-chip by  doxygen 1.5.9