/*! * \brief Perform TWI control functions. * * This function is only available on ATmega128 systems. * * \param req Requested control function. May be set to one of the * following constants: * - TWI_SETSPEED, if conf points to an u_long value containing the bitrate. * - TWI_GETSPEED, if conf points to an u_long value receiving the current bitrate. * \param conf Points to a buffer that contains any data required for * the given control function or receives data from that * function. * \return 0 on success, -1 otherwise. * * \note Timeout is limited to the granularity of the system timer. * */ int TwIOCtl(int req, void *conf) { #ifndef __AVR_ENHANCED__ return -1; #else int rc = 0; u_long lval; switch (req) { case TWI_SETSLAVEADDRESS: TWAR = (*((u_char *) conf) << 1) | 1; break; case TWI_GETSLAVEADDRESS: *((u_char *) conf) = TWAR; break; case TWI_SETSPEED: lval = ((2UL * NutGetCpuClock() / (*((u_long *) conf)) + 1UL) / 2UL - 16UL) / 2UL; if (lval > 1020UL) { lval /= 16UL; sbi(TWSR, TWPS1); } else { cbi(TWSR, TWPS1); } if (lval > 255UL) { lval /= 4UL; sbi(TWSR, TWPS0); } else { cbi(TWSR, TWPS0); } if (lval > 9UL && lval < 256UL) { outb(TWBR, (u_char) lval); } else { rc = -1; } break; case TWI_GETSPEED: lval = 2UL; if (bit_is_set(TWSR, TWPS0)) { lval *= 4UL; } if (bit_is_set(TWSR, TWPS1)) { lval *= 16UL; } *((u_long *) conf) = NutGetCpuClock() / (16UL + lval * (u_long) inb(TWBR)); break; case TWI_GETSTATUS: break; case TWI_SETSTATUS: break; default: rc = -1; break; } return rc; #endif /* __AVR_ENHANCED__ */ }
/* * Main application routine. */ int main(void) { uint32_t baud = 115200; /* * Register the UART device, open it, assign stdout to it and set * the baudrate. */ NutRegisterDevice(&DEV_CONSOLE, 0, 0); freopen(DEV_CONSOLE.dev_name, "w", stdout); _ioctl(_fileno(stdout), UART_SETSPEED, &baud); puts("\n\nNut/OS timer sample"); /* * Display some general info. */ printf("CPU running at %lu Hz\n", NutGetCpuClock()); printf("%lu system ticks per second\n", NutTimerMillisToTicks(1000)); /* * Run the demos. */ OneShotDemo(10); PeriodicDemo(2); DelayDemo(); SleepDemo(); /* Never returns. */ return 0; }
/*! * \brief Set transfer rate for a given device at SPI0. * * \param ix The device index, starting at 0. * \param rate Transfer rate in bits per second. * */ void Sppi0SetSpeed(u_char ix, u_long rate) { u_long fosc; u_char i; fosc = NutGetCpuClock(); sppi0_spcr[ix] &= ~(_BV(SPR1) | _BV(SPR0)); /* Find the frequency that is below or equal the requested one, using the double speed bit if available. */ #if defined(SPI2X) for (i = 0; i < 7; i++) { fosc >>= 1; if (fosc <= rate) { break; } } sppi0_spcr[ix] |= (i >> 1); if (i < 6) { sppi0_spsr[ix] = ~i & 1; } #else for (i = 0; i < 3; i++) { fosc >>= 2; if (fosc <= rate) { break; } } sppi0_spcr[ix] |= i; #endif }
/*! * \brief Handle I/O controls for debug device 0. * * The debug device doesn't support any. * * \return Always -1. */ static int DebugIOCtl(NUTDEVICE * dev, int req, void *conf) { if(req == UART_SETSPEED) { #if defined(__AVR_ENHANCED__) && ((NUT_CPU_FREQ == 12000000) || (NUT_CPU_FREQ == 16000000)) /* On enhanced MCUs with 12.0 or 16.0 MHz we use double rate mode, * so we can use 115200 bps with 12.0 MHz crystals * and 57600 with 16.0 MHz crystals. */ sbi(UCSR0A, U2X0); outb(UBRR, (uint8_t) ((((2UL * NutGetCpuClock()) / (*((uint32_t *)conf) * 8UL)) + 1UL) / 2UL) - 1UL); #else outb(UBRR, (uint8_t) ((((2UL * NutGetCpuClock()) / (*((uint32_t *)conf) * 16UL)) + 1UL) / 2UL) - 1UL); #endif return 0; } return -1; }