plat.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #undef __FILE_ID__
00017 #define __FILE_ID__ 0x70
00018
00019
00023 #include <stdio.h>
00024 #include <avr/io.h>
00025 #include <avr/interrupt.h>
00026 #include <avr/pgmspace.h>
00027 #include <avr/eeprom.h>
00028
00029 #include "pm.h"
00030
00031
00032 #define UART_BAUD 19200UL
00033
00034
00042 #define AVR_DEFAULT_TIMER_SOURCE
00043
00044
00045 #ifdef AVR_DEFAULT_TIMER_SOURCE
00046
00047
00048
00049
00050 #define PLAT_TIME_PER_TICK_USEC (1000000ULL*256ULL*8ULL/F_CPU)
00051
00052 #endif
00053
00054
00055
00056 static int uart_putc(char c, FILE *stream);
00057 static int uart_getc(FILE *stream);
00058 FILE avr_uart = FDEV_SETUP_STREAM(uart_putc, uart_getc, _FDEV_SETUP_RW);
00059
00060
00061
00062
00063
00064
00065 PmReturn_t
00066 plat_init(void)
00067 {
00068
00069
00070
00071 UBRR = (F_CPU / (16UL * UART_BAUD)) - 1;
00072
00073
00074 UCR = _BV(TXEN) | _BV(RXEN);
00075
00076 stdin = stdout = stderr = &avr_uart;
00077
00078
00079 #ifdef AVR_DEFAULT_TIMER_SOURCE
00080
00081
00082
00083 #if (TARGET_MCU == atmega103) || (TARGET_MCU == atmega128)
00084
00085 ASSR &= ~(1<<AS0);
00086
00087 TCCR0 &= ~0x07;
00088 TCCR0 |= (1<<CS01);
00089 #else
00090 #error No timer configuration is implemented for this AVR.
00091 #endif
00092 #endif
00093
00094
00095 return PM_RET_OK;
00096 }
00097
00098
00099 PmReturn_t
00100 plat_deinit(void)
00101 {
00102
00103 UCR &= ~(_BV(TXEN) | _BV(RXEN));
00104
00105 #ifdef AVR_DEFAULT_TIMER_SOURCE
00106 #if (TARGET_MCU == atmega103) || (TARGET_MCU == atmega128)
00107
00108 TCCR0 = 0;
00109 #else
00110 #error No timer configuration is implemented for this AVR.
00111 #endif
00112 #endif
00113
00114 return PM_RET_OK;
00115 }
00116
00117
00118 #ifdef AVR_DEFAULT_TIMER_SOURCE
00119 ISR(TIMER0_OVF_vect)
00120 {
00121
00122
00123
00124
00125 pm_vmPeriodic(PLAT_TIME_PER_TICK_USEC);
00126 }
00127 #endif
00128
00129
00130
00131
00132
00133
00134 uint8_t
00135 plat_memGetByte(PmMemSpace_t memspace, uint8_t const **paddr)
00136 {
00137 uint8_t b = 0;
00138
00139 switch (memspace)
00140 {
00141 case MEMSPACE_RAM:
00142 b = **paddr;
00143 *paddr += 1;
00144 return b;
00145
00146 case MEMSPACE_PROG:
00147 b = pgm_read_byte(*paddr);
00148 *paddr += 1;
00149 return b;
00150
00151 case MEMSPACE_EEPROM:
00152 b = eeprom_read_byte(*paddr);
00153 *paddr += 1;
00154 return b;
00155
00156 case MEMSPACE_SEEPROM:
00157 case MEMSPACE_OTHER0:
00158 case MEMSPACE_OTHER1:
00159 case MEMSPACE_OTHER2:
00160 case MEMSPACE_OTHER3:
00161 default:
00162 return 0;
00163 }
00164 }
00165
00166
00167 static int
00168 uart_getc(FILE *stream)
00169 {
00170 char c;
00171
00172
00173 loop_until_bit_is_set(USR, RXC);
00174 c = UDR;
00175
00176
00177 if (USR & _BV(FE)) return _FDEV_EOF;
00178 if (USR & _BV(DOR)) return _FDEV_ERR;
00179
00180 return c;
00181 }
00182
00183
00184 static int
00185 uart_putc(char c, FILE *stream)
00186 {
00187
00188 loop_until_bit_is_set(USR, UDRE);
00189
00190
00191 UDR = c;
00192
00193 return 0;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 PmReturn_t
00203 plat_getByte(uint8_t *b)
00204 {
00205 PmReturn_t retval = PM_RET_OK;
00206
00207
00208
00209 loop_until_bit_is_set(USR, RXC);
00210
00211
00212 if (USR & (_BV(FE) | _BV(DOR)))
00213 {
00214 PM_RAISE(retval, PM_RET_EX_IO);
00215 return retval;
00216 }
00217 *b = UDR;
00218
00219
00220 return retval;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229 PmReturn_t
00230 plat_putByte(uint8_t b)
00231 {
00232
00233
00234 loop_until_bit_is_set(USR, UDRE);
00235
00236
00237 UDR = b;
00238
00239
00240 return PM_RET_OK;
00241 }
00242
00243
00244
00245
00246
00247
00248 PmReturn_t
00249 plat_getMsTicks(uint32_t *r_ticks)
00250 {
00251
00252 unsigned char _sreg = SREG;
00253 cli();
00254 *r_ticks = pm_timerMsTicks;
00255 SREG = _sreg;
00256
00257 return PM_RET_OK;
00258 }
00259
00260
00261 void
00262 plat_reportError(PmReturn_t result)
00263 {
00264
00265 printf_P(PSTR("Error: 0x%02X\n"), result);
00266 printf_P(PSTR(" Release: 0x%02X\n"), gVmGlobal.errVmRelease);
00267 printf_P(PSTR(" FileId: 0x%02X\n"), gVmGlobal.errFileId);
00268 printf_P(PSTR(" LineNum: %d\n"), gVmGlobal.errLineNum);
00269
00270
00271 {
00272 pPmObj_t pframe;
00273 pPmObj_t pstr;
00274 PmReturn_t retval;
00275
00276 puts_P(PSTR("Traceback (top first):"));
00277
00278
00279 pframe = (pPmObj_t)gVmGlobal.pthread->pframe;
00280
00281
00282 if (pframe == (pPmObj_t)&(gVmGlobal.nativeframe))
00283 {
00284
00285
00286 retval = tuple_getItem((pPmObj_t)gVmGlobal.nativeframe.nf_func->
00287 f_co->co_names, -1, &pstr);
00288 if ((retval) != PM_RET_OK)
00289 {
00290 puts_P(PSTR(" Unable to get native func name."));
00291 return;
00292 }
00293 else
00294 {
00295 printf_P(PSTR(" %s() __NATIVE__\n"), ((pPmString_t)pstr)->val);
00296 }
00297
00298
00299 pframe = (pPmObj_t)gVmGlobal.nativeframe.nf_back;
00300 }
00301
00302
00303 for (;
00304 pframe != C_NULL;
00305 pframe = (pPmObj_t)((pPmFrame_t)pframe)->fo_back)
00306 {
00307
00308 retval = tuple_getItem((pPmObj_t)((pPmFrame_t)pframe)->
00309 fo_func->f_co->co_names, -1, &pstr);
00310 if ((retval) != PM_RET_OK) break;
00311
00312 printf_P(PSTR(" %s()\n"), ((pPmString_t)pstr)->val);
00313 }
00314 puts_P(PSTR(" <module>."));
00315 }
00316 }