ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
30 июня
446711 Топик полностью
fk0, легенда (25.09.2013 12:21, просмотров: 196) ответил FDA на Возмущения от того, что все попиздили тут немного, а конкретики никакой. Начинается опять идиотское письмомерство по поводу кто какой проц применяет и идиотские заявления про то, что Cortex спасёт мир! Во что конфа превращается, непонятно. Лет
...  // #include "iwslave.h" ///////////////////////// contents of iwslave.h /*! переход в состояние требующее сброса (начальное) */ void iwire_reset(void); /*! функция вызывается при старте программы */ int iwire_init(void); //#include "iwslave_hal.c" //////////////////////////// contents of iwslave_hal.c /// XXX файл содержит функции связывающие логику модуля с аппаратурой /* задержка на вход в прерывание, мкс */ #define LATENCY 1 /* пересчёт микросекунд в такты таймера */ #define US2TMR(us) (((us)-LATENCY)*(SYSCLK/4/1000L)/1000L) static NEAR bit iw_pin; /* сохранённое состояние входа */ /* чтение состояния шины */ #define iwire_in_poll() (RB4) #define iwire_in_edge() (iw_pin) /* управление выходом (0 - активный 0, 1 - пассивная 1) */ #define iwire_out(v) do { \ if (!(v)) LATC0=1; \ else LATC0=0; \ } while(0) /* разрешение прерывания от 1-wire */ #define iw_ei() do { RBIE=1; RBIF=0; } while(0) #define iw_di() do { RBIE=0; RBIF=0; } while(0) /* флаг разрешённого прерывания */ #define iw_if() (RBIE) /* флаг прерывания таймера */ #define tint() (TMR3IF) /* обработчик высокоприоритетного прерывания */ #define IWIRE_INTERRUPT_HANDLER() void interrupt iwire_interrupt(void) #define IWIRE_INT_PROLOGUE do { do { iw_pin=RB4; RBIF=0; } while(0) #define IWIRE_INT_EPILOGUE } while((RBIF && RBIE) || (TMR3IF && TMR3IE)) /* короткая задержка на установление сигналов на ножках */ #define iodelay() do { \ asm("nop"); asm("nop"); asm("nop"); asm("nop"); \ } while(0) /* срабатывание таймера через tm тактов таймера */ #define after(tm) do { \ unsigned t=-(tm); \ TMR3ON=0; \ TMR3H=t>>8, TMR3L=t&0xFF; \ TMR3IF=0; \ TMR3ON=1; \ } while(0) /* считывание значения таймера оставшегося до срабатывания */ #define tmget() (-TMR3) /* останов таймера */ #define tmstop() do { \ TMR3ON=0; \ TMR3IF=0; \ } while(0) static void iwire_start_hw(void) { T3CON=0x80; /* RD16=1, no prescaler, Fosc/4 clock source */ TMR3IE=1, TMR3IF=0; TMR3IP=1; /* timer is high priority interrupt */ RBIE=0, RBIF=0; IOCB=0x10; /* interrupts enabled only for RB4 */ RBIP=1; /* pin change is high priority too */ C2IP=0, C2IE=1, C2IF=0; RBIE=1; } static void iwire_stop_hw(void) { TMR3IE=0; C2IE=0; RBIE=0; } static void iwire_init_hw(void) { LATC0=0, TRISC0=0; TRISB4=1; } //////////////// end of iwslave_hal.c //////////////// continue of iwslave.c /////////////////////// /* временные интервалы в мкс */ #define RST_MAX_LENGTH US2TMR(650) /* макс. длительность импульса сброса */ #define RST_MIN_LENGTH US2TMR(450) /* мин. длительность импульса сброса */ #define PRESENCE_PAUSE US2TMR(45-35) /* пауза перед импульсом присутствия */ #define PRESENCE_LENGTH US2TMR(250) /* длительность импульса присутствия */ #define BIT_SAMPLE US2TMR(30) /* считывание бита после начала импульса */ #define BIT_WRITE US2TMR(35) /* длительность импульса записи 0 */ #define BIT_MAX_LENGTH US2TMR(400) /* макс. длительность бита при чтении-записи */ /* состояние автомата */ enum e_iwire_s { IWIRE_RESET=0, IWIRE_READ, IWIRE_WRITE }; NEAR enum e_iwire_s iwire_S; /* вложенные состояния (сброс) */ NEAR static enum { RST0, RST1, RST2, RST3 } iwire_RS; typedef uint_fast8_t iwsize_t; static NEAR uint_fast8_t bits, byte; static uint8_t *NEAR rxdata, *NEAR rxbuf; // TODO объединить rxdata и txdata? static NEAR iwsize_t rxsize; uint8_t *NEAR txdata; static NEAR iwsize_t txsize; /* переход в состояние требующее сброса (начальное) */ void iwire_reset(void) { USE_CRITICAL; BEGIN_CRIT(); tmstop(); iwire_S=IWIRE_RESET, iwire_RS=RST0; END_CRIT(); } /* переход в состояние приёма (из состояния записи), вызывается из iwdevice.c */ #define iwire_read(_data, _size) do { \ iwire_S=IWIRE_READ, bits=8; \ rxbuf=rxdata=/*(void*)*/(_data), rxsize=(_size); \ } while(0) /* переход в состояние записи (передаст указанные данные), вызывается из iwdevice.c */ #define iwire_write(_data, _size) do { \ txdata=/*(const void*)*/(_data), txsize=(_size); \ byte=*txdata++; \ iwire_S=IWIRE_WRITE, bits=8; \ } while(0) /* включение файла реализующего конкретный протокол обмена */ //// XXX файл реализует интерфейс, функции: //// void iw_fail(void) -- вызывается при сбое в обмене //// void iw_reset(void) -- вызывается при приёме сигнала сброса //// void iw_read(iwsize_t size) -- вызывается после принятия данных (буфер задаётся через iwire_read() //// void iw_write(void) -- вызывается после передачи данных (заданных через iwire_write() //// описываемые функции реализуют конечный автомат управлямый вызовами данных //// функций и реализующий логику работы прибора (т.е. iwdevice.c -- только транспортный уровень). //// XXX: принципиально включение через include, т.к. в разных единицах трансляции //// компилятор не будет понимать какие регистры не испольуются и будет сохранять //// все регистры на входе в обработчик прерывания. #include "iwdevice.c" /* обработчик прерывания, tint()==1 если прерывание от таймера */ IWIRE_INTERRUPT_HANDLER() { IWIRE_INT_PROLOGUE; do { if (iwire_S == IWIRE_WRITE) { if (!tint()) { if (iwire_in_edge()) { tmstop(); break; } if (!(byte&1)) { iwire_out(0); iw_di(); after(BIT_WRITE); byte>>=1; break; } byte>>=1; } else if (iw_if()) { after(RST_MAX_LENGTH-BIT_MAX_LENGTH); iwire_S=IWIRE_RESET, iwire_RS=RST1; iw_fail(); break; } else { /* TINT, write 0 */ iw_ei(); iodelay(); iwire_out(1); } /* TINT (write 0) or writing 1 */ bits--; if (!bits) { bits=8; txsize--; if (!txsize) { iwire_S=IWIRE_READ; iw_write(); } else byte=*txdata++; } after(BIT_MAX_LENGTH-BIT_WRITE); break; } else if (iwire_S == IWIRE_READ) { if (!tint()) { if (iwire_in_edge()) { tmstop(); break; } after(BIT_SAMPLE); iw_di(); } else if (!iw_if()) { byte>>=1; if (iwire_in_edge()) byte|=0x80; if (!--bits) { bits=8; if (!rxsize) { iw_ei(); iwire_S=IWIRE_RESET; if (!iwire_in_poll()) { tmstop(); iwire_RS=RST0; } else { after(RST_MAX_LENGTH); iwire_RS=RST1; } iw_fail(); break; } *rxdata++=byte; if (!--rxsize) iw_read(rxdata-rxbuf); } iw_ei(); if (iwire_in_poll()) tmstop(); else after(BIT_MAX_LENGTH-BIT_SAMPLE); } else /* iw_if() */ { after(RST_MAX_LENGTH-BIT_MAX_LENGTH); iwire_S=IWIRE_RESET, iwire_RS=RST1; iw_fail(); } break; } else /* IWIRE_RESET: */ { PSTATIC NEAR unsigned t; switch (iwire_RS) { case RST1: t=-tmget(), t=-t; /* PIC18 suxx */ if (tint()) { tmstop(); iwire_RS=RST0; break; } else if (t >= RST_MAX_LENGTH-RST_MIN_LENGTH) { tmstop(); iwire_RS=RST0; } else if (iwire_in_edge()) { iwire_RS=RST2; after(PRESENCE_PAUSE); iw_di(); } break; case RST2: iwire_out(0); after(PRESENCE_LENGTH); iwire_RS=RST3; break; case RST3: iwire_out(1); tmstop(); iwire_RS=RST0; bits=8; iwire_S=IWIRE_READ; iw_reset(); /*iodelay();*/ iw_ei(); break; case RST0: default: if (iwire_in_edge()) break; after(RST_MAX_LENGTH); iwire_RS=RST1; } } } while(0); IWIRE_INT_EPILOGUE; } /* функция вызывается при старте программы */ int iwire_init() { uint_fast8_t v; ftime_t t; iwire_init_hw(); iwire_stop_hw(); /* test */ iwire_out(0); iodelay(); iodelay(); iodelay(); iodelay(); if (iwire_in_poll()) { iwire_out(1); writelog(LOG_CRIT, "1-wire output(0) failure (can't set to zero)"); return -1; } iwire_out(1); t=timer(); v=0; do { if (iwire_in_poll()) { v=1; break; } } while (timer()-t < FTIME_PER_SEC/1000); if (!v) { writelog(LOG_CRIT, "1-wire intput failure (always 0, must be 1)"); return -1; } iwire_S=IWIRE_RESET, iwire_RS=RST0; iwire_start_hw(); iwire_reset(); return 0; }
[ZX]