ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
25 ноября
191469 Топик полностью
fk0, легенда (23.04.2010 11:45, просмотров: 107) ответил Athlon64 на При выполнении
Смотрите, может поможет (или запросите у меня полный исходник: fk0@fk0.name):  void smb_init(void) { AT91S_PIO *pio = AT91C_BASE_PIOA; pio->PIO_SODR = AT91C_PA10_TWD | AT91C_PA11_TWCK; pio->PIO_PER = AT91C_PA10_TWD | AT91C_PA11_TWCK; pio->PIO_IFER = AT91C_PA10_TWD | AT91C_PA11_TWCK; pio->PIO_MDER = AT91C_PA10_TWD | AT91C_PA11_TWCK; pio->PIO_PPUDR = AT91C_PA10_TWD | AT91C_PA11_TWCK; pio->PIO_ASR = AT91C_PA10_TWD | AT91C_PA11_TWCK; AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TWI] = (uint32_t)smb_intr; smb_ei(); } bool smb_hwreset(void) { AT91S_TWI *twi = AT91C_BASE_TWI; uint32_t sr; twi->TWI_IDR = -1; twi->TWI_CR = AT91C_TWI_SWRST; /* compute C[LHK]DIV */ uint8_t CLDIV, CHDIV; uint8_t CKDIV; { uint8_t v; unsigned n; v = (MCK / 1000 / config.bus.freq - 3) / 256; CKDIV = 0; while (v > 0) v /= 2, CKDIV++; n = (MCK / 1000 / config.bus.freq - 3) / (1 << CKDIV); CHDIV = config.bus.ratio * n / 100; CLDIV = n - CHDIV; } twi->TWI_CWGR = (CKDIV << 16) | (CHDIV << 8) | CLDIV; twi->TWI_CR = AT91C_TWI_MSDIS; twi->TWI_CR = AT91C_TWI_MSEN; sr = twi->TWI_SR; if ((sr & AT91C_TWI_TXCOMP) && (sr & AT91C_TWI_TXRDY)) return 1; else return 0; } #define smb_txbyte(byte) { AT91C_BASE_TWI->TWI_THR=(byte); } #define smb_rxbyte() (AT91C_BASE_TWI->TWI_RHR) static inline void smb_wait_tx(void) { AT91S_TWI *twi = AT91C_BASE_TWI; twi->TWI_IDR = -1; twi->TWI_IER = AT91C_TWI_NACK | AT91C_TWI_TXRDY /*|AT91C_TWI_TXCOMP */ ; } void smb_start_tx(uint_least8_t addr, uint_least8_t byte) { AT91S_TWI *twi = AT91C_BASE_TWI; AT91S_PIO *pio = AT91C_BASE_PIOA; pio->PIO_PDR = AT91C_PA10_TWD | AT91C_PA11_TWCK; twi->TWI_MMR = AT91C_TWI_DADR & (addr << 16); /* MREAD=0 */ smb_wait_tx(); smb_txbyte(byte); //twi->TWI_CR=AT91C_TWI_START; } static inline void smb_wait_rx(void) { AT91S_TWI *twi = AT91C_BASE_TWI; twi->TWI_IDR = -1; twi->TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK /*| AT91C_TWI_TXCOMP */ ; } static inline void smb_rx_last(void) { AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP; } void smb_start_rx(uint_least8_t addr) { AT91S_TWI *twi = AT91C_BASE_TWI; AT91S_PIO *pio = AT91C_BASE_PIOA; pio->PIO_PDR = AT91C_PA10_TWD | AT91C_PA11_TWCK; twi->TWI_MMR = (AT91C_TWI_DADR & (addr << 16)) | AT91C_TWI_MREAD; smb_rxbyte(); // XXX I don't know why, but it helps... smb_wait_rx(); twi->TWI_CR = AT91C_TWI_START; } inline static void smb_stop(void) { AT91S_TWI *twi = AT91C_BASE_TWI; twi->TWI_CR = AT91C_TWI_STOP; twi->TWI_IDR = -1; twi->TWI_IER = AT91C_TWI_TXCOMP; } void smb_off(void) { AT91S_PIO *pio = AT91C_BASE_PIOA; pio->PIO_OER = AT91C_PA11_TWCK | AT91C_PA10_TWD; pio->PIO_PER = AT91C_PA10_TWD | AT91C_PA11_TWCK; AT91C_BASE_TWI->TWI_IDR = -1; unsigned n; for (n = 0; n <= 12; n++) { delay2us(); pio->PIO_CODR = AT91C_PA11_TWCK; delay2us(); pio->PIO_CODR = AT91C_PA10_TWD; delay2us(); pio->PIO_SODR = AT91C_PA11_TWCK; delay2us(); pio->PIO_SODR = AT91C_PA10_TWD; } delay2us(); pio->PIO_ODR = AT91C_PA11_TWCK | AT91C_PA10_TWD; } #define RXRDY() (SR & AT91C_TWI_RXRDY) #define TXRDY() (SR & AT91C_TWI_TXRDY) #define ISACK() (!(SR & AT91C_TWI_NACK)) #define ISSTOP() (SR & AT91C_TWI_TXCOMP)
[ZX]