123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- /*
- * Transmit an FM-modulated signal using the USART in SPI master mode.
- * As per ABC standard, this signal is transmitted LSB first.
- */
- #include "usbcas.h"
- /*
- * FM nybble patters; these should be transmitted LSB first
- * and XOR'd with the MSB of the pattern byte last transmitted.
- */
- static const uint8_t fm_nyb[16] = {
- 0x33, 0xcd, 0xcb, 0x35, 0xd3, 0x2d, 0x2b, 0xd5,
- 0xb3, 0x4d, 0x4b, 0xb5, 0x53, 0xad, 0xab, 0x55
- };
- static uint8_t parity = 0;
- /*
- * Send the least significant nybble of this data item and return
- * the next nybble, if any. Check with fmtx_send_ready() before
- * calling this function.
- */
- uint8_t fmtx_send_nybble(uint8_t d)
- {
- uint8_t nyb = fm_nyb[d & 15] ^ parity;
- UCSR1A = (1 << TXC1);
- UDR1 = nyb;
- parity = -((int8_t)nyb < 0);
- return d >> 4;
- }
- /*
- * Synchronize transmitter before reconfiguration
- */
- void fmtx_drain(void)
- {
- while (!(UCSR1A & (1 << TXC1)))
- ;
- }
- /*
- * Initialize the USART hardware and set transmission baudrate.
- * This is mostly the same as SerialSPI_Init().
- */
- void fmtx_init_speed(uint32_t baudrate)
- {
- DDRD |= 0x28; /* PD3 = outdata, PD5 = XCK/TXLED */
- PORTD = (PORTD & ~0x28) | (parity & 0x20) | 0x08;
- UCSR1B = 0; /* Disable USART */
- UCSR1A = 0; /* Clear error bits */
- /*
- * SPI master mode, mode 1, LSB first
- * UCPHA doesn't matter, but have UCPOL=1 to that the clock
- * is 1 when idle and the TXLED is OFF.
- */
- UCSR1C = (3 << UMSEL10) | (1 << UDORD1) | (1 << UCPOL1);
- /* UBRR must be zero when the transmitter is enabled */
- UBRR1 = 0;
- /* Enable transmitter, but not receiver */
- UCSR1B = (1 << TXEN1);
- /* Configure baud rate (UBBRVAL is a typo in LUFA) */
- /* We need two SPI ticks per symbol, hence double... */
- UBRR1 = SERIAL_SPI_UBBRVAL(baudrate << 1);
- /* Output the current idle state of the line */
- UDR1 = parity;
- }
|