Port Multiplexing - Changing location of TCA00 on ATTiny 1614 #544
Replies: 1 comment
-
No automatic way - we use a bunch of tricks to shrink the code profile of the mapping between arduino pin numbers and waveform output channels in analogWrite(), and the layout on the tinyAVR parts isn't friendly to that (and we don't have the flash to throw around here) so I couldn't justify it (automatic detection is just as much flash and execution time in this case as a swap-type function), so I wasn't able to do the sort of thing I did on DxCore where it will just detect the PORTMUX option for TCA PWM pins. Here you have to do a full takeover of the timer and replace the analogWrite() function with something else. I threw together a quick demo and added it to the end of https://github.com/SpenceKonde/megaTinyCore/blob/master/megaavr/extras/TakingOverTCA0.md On DxCore, the autolookup is just if (port == (PORTMUX.TCA0ROUTEA & PORTMUX_TCA0_gm)) { // then the timer is pointed at this port - and we needed to look up the port anyway to set the pin output anyway; and on every port, it it's TCA0's port, pins 0-5 get the PWM, and the pin's bitmask gets processed to find the register and enable bit. Here, the combination of PORTMUX working on a per-pin basis, and the wacky layout - if it's not port b, (bitmask & 0b00111000) means it could have PWM, if it's a pin on PORTC, then it's got pwm if (bitmask & 0b00111000 & PORTMUX.CTRLC), otherwise it's on portA and has PWM if that that's not true either way the, and for portb you see if bitmask > 0b00000100 and if it is, rightshift thrice (which the compiler likes to do with a loop even when it's dumb to do so, like it is here) and take bitwise and with portmux value finally with 0x07, and if non-zero there's pwm there. (then it could proceed with the current codepath) It's pretty ugly. But if you do the work of keeping the WOn numbers straight, code, if repetitive, is dead simple comes out tiny. |
Beta Was this translation helpful? Give feedback.
-
My project requires 4 PWM outputs, IIC, SPI, and I'm using a ATTiny 1614. TCA00 shares a pin with SCK and I need to use multiplexing to move TCA00 to its alternate location. I'm wondering if there's any function similar to Serial.swap() or SPI.swap() for the timer pins? Or how can I do it using port manipulation? I haven't really used port manipulation much before so I feel a little over my head trying to figure that out but tried using PORTMUX.CTRLC = PORTMUX_TCA00_bm; in the setup function in the program below. This was to no avail.
`#include <avr/io.h>
#include <Arduino.h>
int testPin = 4;
void setup() {
PORTMUX.CTRLC = PORTMUX_TCA00_bm;
pinMode(testPin,OUTPUT);
digitalWrite(testPin,HIGH);
delay(1000);
digitalWrite(testPin, LOW);
}
void loop() {
for (int i = 0; i < 255; i++)
{
analogWrite(testPin, i);
delay(10);
}
delay(500);
for (int i = 255; i > 0; i--)
{
analogWrite(testPin, i);
delay(10);
}
delay(500);
}`
Beta Was this translation helpful? Give feedback.
All reactions