Uses the RP2040's Programmable IO to create a PAL colour video signal. It consists of the PIO program, some "driver" and tools code, a test program and a program for creating colour Look-up Tables (LUTs).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
rppico-pio-pal/analogVideoDriver.h

97 lines
2.5 KiB

#include "hardware/dma.h"
#include "hardware/pio.h"
#include "hardware/irq.h"
#include <stdio.h>
#ifndef ANALOG_VIDEO_DRIVER_H__
#define ANALOG_VIDEO_DRIVER_H__
#define ANALOG_VIDEO_N_GPIOS 4
// status flags for house keeping
#define AV_STATUS_STOPPED 32
#define AV_STATUS_INITIALIZED 64
#define AV_STATUS_ACTIVE 128
// state flags so the application can request what's going on right now
#define AV_STATE_VBLANK 1
#define AV_STATE_VIDEO 2
#define AV_STATE_OVERSCAN 4
#define AV_STATE_EVEN_HALF_IMAGE 8
#define AV_STATE_ODD_HALF_IMAGE 16
#define AV_STATE_MASK 0x1f
#define AV_ERR_OK 0
#define AV_ERR_STATUS 1
#define AV_ERR_INVALID_PARAMETERS 2
typedef struct {
int x, y;
} xy;
// contains all the data required by the driver
typedef struct {
// PIO instance
PIO pioInstance;
uint pioProgOff, pioSM;
// GPIOs used by PIO
uint dacBase;
uint vBlankPin;
// DMA
uint dmaChannelId;
dma_channel_config dmaChannelConf;
// callback functions
void (*cbHBlank)(uint, uint*);
void (*cbVBlank)(void);
void (*cbDbg)(uint, uint);
} AnalogVideo;
void analogVideoInit(PIO pio, uint gpioBase, uint vBlankPin);
void analogVideoGetResolution(xy *res);
uint getColourCount();
// used to set the active video area as most TVs will not display some lines
// at the beginning and end of each frame. The driver will automatically
// transmit "black" for these.
uint setLineSkip(uint skipPre, uint skipPost);
uint setColSkip(uint skipPre, uint skipPost);
void putPixelRGB(uint *buffer, uint r, uint g, uint b);
void putPixel(uint *buffer, uint idx);
// start video generation. Allows to pass two callback functions which are called to notify
// applications about horizontal and vertical blank.
// cbHBlank(uint nextLine, uint *videoBuffer) is called after DMA has transfered all data of
// the current video line and takes the next line's Y coordinate and the buffer to write
// pixel data to as parameters.
// cbVBlank() is called when the vertical blank period starts.
// NOTE: you should NOT render in cbHBlank() as it is called from an interrupt context.
// See paltest.c for an asynchronous implementation using a semaphore.
uint analogVideoStart(void (*cbHBlank)(uint, uint*), void (*cbVBlank)(void));
// stop video output generation
uint analogVideoStop();
uint analogVideoStatus();
// some functions for debugging
void setDebugIsrCallback(void (*cbDbg)(uint, uint));
uint dbgGetProgOffset();
uint dbgGetDMAState();
void printDebugInfo();
// can be used to test different parts of the PIO code
uint enterTestMode(uint what);
#endif