/* Copyright (C) 2018 Evariste COURJAUD F5OEO This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "stdio.h" #include "atv.h" #include "gpio.h" #include #include #include #include #include //#define CB_ATV (6 * 4 + 5 * 4 + 5 * 4 + (304 + 305) * (4 + 52 * 2)) #define CB_ATV 70000 atv::atv(uint64_t TuneFrequency, uint32_t SR, int Channel, uint32_t Lines) : dma(Channel, CB_ATV, Lines * 52 + 3) // Need 2 more bytes for 0 and 1 // Need 6 CB more for sync, if so as 2CBby sample : 3 { SampleRate = SR; tunefreq = TuneFrequency; clkgpio::SetAdvancedPllMode(true); clkgpio::SetCenterFrequency(TuneFrequency, SampleRate); clkgpio::SetFrequency(0); clkgpio::enableclk(4); // GPIO 4 CLK by default syncwithpwm = true; if (syncwithpwm) { pwmgpio::SetPllNumber(clk_plld, 1); pwmgpio::SetFrequency(SampleRate); } else { pcmgpio::SetPllNumber(clk_plld, 1); pcmgpio::SetFrequency(SampleRate); } padgpio pad; Originfsel = pad.gpioreg[PADS_GPIO_0]; usermem[(usermemsize - 2)] = (0x5A << 24) + (1 & 0x7) + (1 << 4) + (0 << 3); // Amp 1 usermem[(usermemsize - 1)] = (0x5A << 24) + (0 & 0x7) + (1 << 4) + (0 << 3); // Amp 0 usermem[(usermemsize - 3)] = (0x5A << 24) + (4 & 0x7) + (1 << 4) + (0 << 3); // Amp 4 SetDmaAlgo(); } atv::~atv() { clkgpio::disableclk(4); padgpio pad; pad.gpioreg[PADS_GPIO_0] = Originfsel; } void atv::SetDmaAlgo() { dma_cb_t *cbp = cbarray; int LineResolution = 625; uint32_t level0 = mem_virt_to_phys(&usermem[(usermemsize - 1)]); uint32_t level1 = mem_virt_to_phys(&usermem[(usermemsize - 2)]); uint32_t level4 = mem_virt_to_phys(&usermem[(usermemsize - 3)]); uint32_t index_level0 = usermemsize - 1; uint32_t index_level1 = usermemsize - 2; uint32_t index_level4 = usermemsize - 3; int shortsync_0 = 2; int shortsync_1 = 30; int longsync_0 = 30; int longsync_1 = 2; int normalsync_0 = 4; int normalsync_1 = 6; int frontsync_1 = 2; for (int frame = 0; frame < 2; frame++) { //Preegalisation //6*4*2FrameCB for (int i = 0; i < 5 + frame; i++) { //2us 0,30us 1 //@0 //SYNC preegalisation 2us SetEasyCB(cbp++, index_level0, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, shortsync_0); //SYNC preegalisation 30us SetEasyCB(cbp++, index_level1, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, shortsync_1); } //SYNC top trame 5*4*2frameCB for (int i = 0; i < 5; i++) { SetEasyCB(cbp++, index_level0, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, longsync_0); SetEasyCB(cbp++, index_level1, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, longsync_1); } //postegalisation ; copy paste from preegalisation //5*4*2CB for (int i = 0; i < 5 + frame; i++) { //2us 0,30us 1 //@0 //SYNC preegalisation 2us SetEasyCB(cbp++, index_level0, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, shortsync_0); //SYNC preegalisation 30us SetEasyCB(cbp++, index_level1, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, shortsync_1); } //(304+305)*(4+52*2+2)CB for (int line = 0; line < 305 /* 317 + frame*/; line++) { //@0 //SYNC 0/ 5us SetEasyCB(cbp++, index_level0, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, normalsync_0); //SYNC 1/ 5us SetEasyCB(cbp++, index_level1, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, normalsync_1); for (uint32_t samplecnt = 0; samplecnt < 52; samplecnt++) //52 us { SetEasyCB(cbp++, samplecnt + line * 52 + frame * 312 * 52, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, 1); } //FRONT PORSH //SYNC 2us SetEasyCB(cbp++, index_level1, dma_pad, 1); SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, frontsync_1); } } cbp--; cbp->next = mem_virt_to_phys(cbarray); // We loop to the first CB fprintf(stderr, "Last cbp : %d \n", ((unsigned int)(cbp) - (unsigned int)(cbarray)) / sizeof(dma_cb_t)); } void atv::SetFrame(unsigned char *Luminance, size_t Lines) { for (size_t i = 0; i < Lines; i++) { for (size_t x = 0; x < 52; x++) { int AmplitudePAD = (Luminance[i * 52 + x] / 255.0) * 6.0 + 1; //1 to 7 if (i % 2 == 0) // First field usermem[i * 52 / 2 + x] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD else usermem[(i - 1) * 52 / 2 + x + 52 * 312] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD } } }