I am trying to build a project using an ATtiny1604.
I need to use PWM (to control a servo) and TWI (to talk to a transducer) and Serial (for debug oputput and command entry) but the default pin assignments clash.
Looking at data sheet, there are no alternative pin assignments for TWI SCL or SDA on my device so that prevents my using TCA0 PWM signal output on WO0 and WO1.
I found a reference to using Serial.swap(); just after the Serial.begin(); statement and I was hoping this would use the alternate pins for TxD, RxD (PA1, PA2) so that the default TxD, Rxd pins (PB2, PB3) would be released.
If this were the case, I could then use WO2 or the alternate WO0 pin for the PWM output.
I have a stripped down version to illustrate my problem.
How do you cause Serial to use the alternate pins on an ATtiny1604?
// ATtiny1604_Serial_Test
// Target ATtiny1604
#include <Arduino.h>
/* ATtiny1604 / ARDUINO Pins
* _____
* VDD 1|* |14 GND
* (nSS) (AIN4) PA4 0~ 2| |13 10~ PA3 (AIN3)(SCK)(EXTCLK)
* (AIN5) PA5 1~ 3| |12 9 PA2 (AIN2)(MISO)
* (DAC) (AIN6) PA6 2 4| |11 8 PA1 (AIN1)(MOSI)
* (AIN7) PA7 3 5| |10 11 PA0 (nRESET/UPDI)
* (RXD) (TOSC1) PB3 4 6| |9 7~ PB0 (AIN11)(SCL)
* (TXD) (TOSC2) PB2 5~ 7|_____|8 6~ PB1 (AIN10)(SDA)
*/
/* Alternate pins
Pin Name Other ADC0 AC0 USART0 SPIO TWI0 TCA0 TCB0 CCL
1 VDD
2 PA4 AIN4 XDIR(*) SS WO4 LUT0-OUT
3 PA5 AIN5 OUT WO5 WO
4 PA6 AIN6 AINN0
5 PA7 AIN7 AINP0 LUT1-OUT
6 PB3 RxD WO0(*)
7 PB2 EVOUT1 TxD WO2
8 PB1 AIN10 XCK SDA WO1
9 PB0 AIN11 XDIR SCL WO0
10 PA0 RESET/UPDI AIN0 LUT0-IN0
11 PA1 AIN1 TxD(*) MOSI LUT0-IN1
12 PA2 EVOUT0 AIN2 RxD(*) MISO LUT0-IN2
13 PA3 EXTCLK AIN3 XCK(*) SCK WO3
14 GND
*/
#define Serial_BAUD 19200
// declare functions here
void system_init();
void setup() {
// put your setup code here, to run once:
system_init();
Serial.begin(Serial_BAUD);
Serial.swap();
/* The default TxD, RxD pins are PB2, PB3
// I was hoping that Serial.swap() would use the alternate pins for
// TxD, RxD would be used (PA1, PA2) but this is not the case.
*/
Serial.println(F("\r\nStart"));
delay(500);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println(F("Loop"));
delay(500);
}
// put function definitions here:
// Initialization routines
void mcu_init() // MCU initialization
{
/* On AVR devices all peripherals are enable from power on reset, this
* disables all peripherals to save power. Driver shall enable
* peripheral if used.
*/
// Set all PORT A pins to low power mode and input disabled
for (uint8_t i = 0; i < 8; i++) { // PA0 - PA7
uint8_t *port_pin_ctrl = ((uint8_t *)&PORTA + 0x10 + i);
*port_pin_ctrl |= (1 << PORT_PULLUPEN_bp); // define pull up
*port_pin_ctrl = (*port_pin_ctrl & ~PORT_ISC_gm) | PORT_ISC_INTDISABLE_gc; // disable input sensing
}
// Set all PORT B pins to low power mode and input disabled
for (uint8_t i = 0; i < 4; i++) { // PB0 - PB3 on ATtiny1604
uint8_t *port_pin_ctrl = ((uint8_t *)&PORTB + 0x10 + i);
*port_pin_ctrl |= (1 << PORT_PULLUPEN_bp); // define pull up
*port_pin_ctrl = (*port_pin_ctrl & ~PORT_ISC_gm) | PORT_ISC_INTDISABLE_gc; // disable input sensing
}
}
void system_init(){ // system initialization
mcu_init();
}
I can work round the issue by using SoftwareSerial and specifying the pins I want to use but this seems 'cluncky' when I think I should be able to use Serial (and the USART).