Disabled external gits
This commit is contained in:
14
cs309-psoc/lab_4_1/sw/hps/application/client-sfml/Makefile
Normal file
14
cs309-psoc/lab_4_1/sw/hps/application/client-sfml/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
CC=g++
|
||||
LDLIBS=`pkg-config --libs sfml-graphics sfml-window sfml-network`
|
||||
|
||||
all: main
|
||||
|
||||
main.o: main.cpp
|
||||
main: main.o
|
||||
|
||||
run:
|
||||
@./main
|
||||
|
||||
clean:
|
||||
rm -f main.o main
|
120
cs309-psoc/lab_4_1/sw/hps/application/client-sfml/main.cpp
Normal file
120
cs309-psoc/lab_4_1/sw/hps/application/client-sfml/main.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
using namespace std;
|
||||
|
||||
#define IMAGE_WIDTH 80
|
||||
#define IMAGE_HEIGHT 60
|
||||
#define SCALE_FACTOR 10
|
||||
#define UPDATE_INTERVAL IMAGE_HEIGHT
|
||||
|
||||
#define SERVER_PORT 25700
|
||||
#define BUFFER_SIZE (4 + IMAGE_WIDTH * 2)
|
||||
#define HANDSHAKE_TIMEOUT 2000
|
||||
|
||||
void updateLine(uint8_t* buffer, uint32_t lineIndex, uint16_t* line);
|
||||
void bernsteinRGB(uint8_t* rgba, double t);
|
||||
void sendHandshake(sf::UdpSocket& socket, sf::IpAddress address, unsigned short port);
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
cout << "Invalid usage of client. You should pass the address of the server." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// We create the window to which we render the image
|
||||
sf::RenderWindow window(sf::VideoMode(IMAGE_WIDTH * SCALE_FACTOR, IMAGE_HEIGHT * SCALE_FACTOR), "Thermalizer", sf::Style::Close);
|
||||
|
||||
// The intermediate buffer in which the image is received before being sent to the GPU
|
||||
uint8_t buffer[IMAGE_HEIGHT * IMAGE_WIDTH * 4]; // RGBA = 4 bytes per pixel
|
||||
size_t lastRefresh = 0; // the number of lines since the last refresh
|
||||
uint32_t lineIndex = 0; // the index of the last line that was received
|
||||
|
||||
// The texture to which the image will be drawn
|
||||
sf::Texture texture;
|
||||
texture.create(IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||
sf::Sprite sprite;
|
||||
sprite.setTexture(texture);
|
||||
sprite.setScale(SCALE_FACTOR, SCALE_FACTOR);
|
||||
|
||||
// The buffer in which the packet for the lines are received
|
||||
char lineBuffer[BUFFER_SIZE];
|
||||
size_t received;
|
||||
sf::IpAddress serverAddress(argv[1]), senderAddress;
|
||||
unsigned short serverPort = SERVER_PORT, senderPort;
|
||||
|
||||
// Create the UDP socket
|
||||
cout << "Creating and binding a UDP socket..." << endl;
|
||||
sf::UdpSocket socket;
|
||||
sf::SocketSelector selector;
|
||||
if (socket.bind(sf::UdpSocket::AnyPort) != sf::Socket::Done) {
|
||||
cout << "Couldn't bind socket on port " << socket.getLocalPort() << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
cout << "UDP Socket successfully bound." << endl;
|
||||
sendHandshake(socket, serverAddress, serverPort);
|
||||
selector.add(socket);
|
||||
|
||||
while (window.isOpen()) {
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event)) {
|
||||
// If the user requested the window to be closed
|
||||
if (event.type == sf::Event::Closed ||
|
||||
(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Q)) {
|
||||
// Inform the server about the client stopping
|
||||
socket.send(nullptr, 0, serverAddress, serverPort);
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (selector.wait(sf::milliseconds(500))) {
|
||||
// If a packet was received, we update the intermediate buffer
|
||||
socket.receive(lineBuffer, BUFFER_SIZE, received, senderAddress, senderPort);
|
||||
lineIndex = *((uint32_t*) lineBuffer);
|
||||
updateLine(buffer, lineIndex, (uint16_t*) (lineBuffer + sizeof(uint32_t)));
|
||||
lastRefresh++;
|
||||
} else {
|
||||
// If no packet was received in a while, we re-send a handshake to try to reconnect
|
||||
sendHandshake(socket, serverAddress, serverPort);
|
||||
}
|
||||
|
||||
// We refresh the image every once in a while, so that if there is packet loss on the last
|
||||
// line the screen is still updated.
|
||||
if (lastRefresh == UPDATE_INTERVAL || lineIndex == IMAGE_HEIGHT - 1) {
|
||||
// If enough packets were received, we update the texture
|
||||
lastRefresh = 0;
|
||||
texture.update(buffer);
|
||||
|
||||
// And draw it to the screen
|
||||
window.clear();
|
||||
window.draw(sprite);
|
||||
window.display();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the line of the buffer with the packet that arrived
|
||||
void updateLine(uint8_t* buffer, uint32_t lineIndex, uint16_t* line) {
|
||||
uint8_t* lineBuffer = buffer + lineIndex * IMAGE_WIDTH * 4;
|
||||
|
||||
for (size_t x = 0; x < IMAGE_WIDTH; x++)
|
||||
bernsteinRGB(lineBuffer + x * 4, (double) line[x] / 0x3FFF);
|
||||
}
|
||||
|
||||
// Performs the color interpolation using Bernstein polynomials
|
||||
void bernsteinRGB(uint8_t* rgba, double t) {
|
||||
rgba[0] = (9 * (1 - t) * t * t * t) * 255;
|
||||
rgba[1] = (15 * (1 - t) * (1 - t) * t * t) * 255;
|
||||
rgba[2] = (9 * (1 - t) * (1 - t) * (1 - t) * t) * 255;
|
||||
rgba[3] = 255;
|
||||
}
|
||||
|
||||
// Sends a handshake to the server
|
||||
void sendHandshake(sf::UdpSocket& socket, sf::IpAddress address, unsigned short port) {
|
||||
cout << "Sending a handshake to the server..." << endl;
|
||||
socket.send(nullptr, 0, address, port);
|
||||
}
|
5
cs309-psoc/lab_4_1/sw/hps/application/client/Makefile
Normal file
5
cs309-psoc/lab_4_1/sw/hps/application/client/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
LDLIBS= -lcaca
|
||||
CFLAGS= -Wall
|
||||
|
||||
main: main.o
|
||||
main.o: main.c
|
216
cs309-psoc/lab_4_1/sw/hps/application/client/main.c
Normal file
216
cs309-psoc/lab_4_1/sw/hps/application/client/main.c
Normal file
@@ -0,0 +1,216 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <caca.h>
|
||||
|
||||
#define ERR -1
|
||||
#define NO_ERR 0
|
||||
|
||||
#define M_REQUIRE(cond_, mess_, ...) \
|
||||
do{ \
|
||||
if(!(cond_)){ \
|
||||
fprintf(stderr, mess_, ##__VA_ARGS__); \
|
||||
return ERR; \
|
||||
} \
|
||||
}while(0);
|
||||
|
||||
#define M_REQUIRE_NO_ERR(v, mess_, ...)\
|
||||
M_REQUIRE(v==NO_ERR, mess_, ##__VA_ARGS__)
|
||||
|
||||
#define M_REQUIRE_NO_NULL(v, mess_, ...)\
|
||||
M_REQUIRE(v!=NULL, mess_, ##__VA_ARGS__)
|
||||
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
#define DEFAULT_PORT 25700
|
||||
|
||||
#define IM_WIDTH 80
|
||||
#define IM_HEIGHT 60
|
||||
#define IM_BPP 16
|
||||
#define IM_TOTAL IM_WIDTH*IM_HEIGHT
|
||||
|
||||
#define PCKT_SIZE (IM_WIDTH*sizeof(pix_t)+sizeof(uint32_t))
|
||||
|
||||
#define PX_MAX_V 0x3FFF
|
||||
|
||||
#define IM_MR 0xFF00
|
||||
#define IM_MG 0x0000
|
||||
#define IM_MB 0x00FF
|
||||
#define IM_MA 0x0000
|
||||
|
||||
#define IM_5B 0x1F
|
||||
|
||||
#define REF_DIV 1
|
||||
|
||||
|
||||
typedef uint16_t pix_t;
|
||||
typedef struct sockaddr_in saddr_t;
|
||||
|
||||
/*=================================================================================================*/
|
||||
|
||||
|
||||
pix_t IMG_IN[IM_TOTAL] = {0};
|
||||
caca_canvas_t* cv = NULL;
|
||||
caca_display_t* dp = NULL;
|
||||
caca_dither_t* dither;
|
||||
int ww = 0, wh = 0;
|
||||
uint64_t msg_cnt = 0;
|
||||
uint8_t refresh = 0;
|
||||
|
||||
char event = 0;
|
||||
|
||||
/*=================================================================================================*/
|
||||
|
||||
int setup_caca(){
|
||||
cv = caca_create_canvas(IM_WIDTH,IM_HEIGHT);
|
||||
M_REQUIRE_NO_NULL(cv, "Error: Unable to create caca canvas\n");
|
||||
dp = caca_create_display(cv);
|
||||
M_REQUIRE_NO_NULL(dp, "Error: Unable to create caca canvas\n");
|
||||
caca_set_display_title(dp,"CACA HEAT VIEWER");
|
||||
ww = caca_get_canvas_width(cv);
|
||||
wh = caca_get_canvas_height(cv);
|
||||
|
||||
#ifdef COLORING_RB
|
||||
dither = caca_create_dither(IM_BPP,IM_WIDTH,IM_HEIGHT,IM_WIDTH*sizeof(pix_t),IM_MR,IM_MG,IM_MB,IM_MA);
|
||||
#else
|
||||
dither = caca_create_dither(IM_BPP,IM_WIDTH,IM_HEIGHT,IM_WIDTH*sizeof(pix_t),IM_5B<<10,IM_5B<<5,IM_5B,IM_MA);
|
||||
#endif
|
||||
|
||||
caca_refresh_display(dp);
|
||||
return NO_ERR;
|
||||
}
|
||||
|
||||
int clear_caca(){
|
||||
caca_free_display(dp);
|
||||
caca_free_canvas(cv);
|
||||
return NO_ERR;
|
||||
}
|
||||
|
||||
int get_server_addr(const char* ip, const uint16_t port, struct sockaddr_in* const p_server_addr){
|
||||
assert(p_server_addr != NULL);
|
||||
|
||||
struct sockaddr_in server_addr = {0};
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(port);
|
||||
if(ip == NULL){
|
||||
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
}else{
|
||||
M_REQUIRE(inet_aton(ip, &server_addr.sin_addr)== 1, "Error: Unable to set server adress (IP)\n");
|
||||
}
|
||||
*p_server_addr = server_addr;
|
||||
return NO_ERR;
|
||||
}
|
||||
|
||||
int bind_server(const int socket, const uint16_t port){
|
||||
struct sockaddr_in server_addr;
|
||||
M_REQUIRE_NO_ERR(get_server_addr(NULL, port, &server_addr), "Error: Unable to get server adress\n");
|
||||
M_REQUIRE_NO_ERR(bind(socket, (const struct sockaddr*) &server_addr, sizeof(server_addr)), " Error: Unable to bind socket\n");
|
||||
return NO_ERR;
|
||||
}
|
||||
|
||||
pix_t bernstein_rgb(float f){
|
||||
uint8_t r = (9*(1-f) *f *f *f)*IM_5B;
|
||||
uint8_t g = (15*(1-f) *(1-f) *f *f)*IM_5B;
|
||||
uint8_t b = (9*(1-f) *(1-f) *(1-f) *f)*IM_5B;
|
||||
return r<<10 | g<<5 | b;
|
||||
}
|
||||
|
||||
pix_t custom_rb(float f){
|
||||
uint8_t r = f*0xFF ;
|
||||
uint8_t b = (1-f)*0xFF;
|
||||
return r<<8 | b;
|
||||
}
|
||||
|
||||
void adjust_row(uint32_t row){
|
||||
for(size_t i = 0; i < IM_WIDTH; ++i){
|
||||
#ifdef COLORING_RB
|
||||
IMG_IN[row*IM_WIDTH+i] = custom_rb((float)IMG_IN[row*IM_WIDTH+i]/PX_MAX_V);
|
||||
#else
|
||||
IMG_IN[row*IM_WIDTH+i] = bernstein_rgb((float)IMG_IN[row*IM_WIDTH+i]/PX_MAX_V);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int handle_message(ssize_t in_msg_len, uint8_t* in_msg){
|
||||
M_REQUIRE_NO_NULL(in_msg,"Error: input message is null\n");
|
||||
M_REQUIRE(in_msg_len >=0, "Error: server message timeout\n");
|
||||
M_REQUIRE(in_msg_len == PCKT_SIZE, "Error: message with wrong length (%zu)\n",in_msg_len);
|
||||
|
||||
uint32_t row = (uint32_t) in_msg[0];
|
||||
if(row < IM_HEIGHT){
|
||||
memcpy(IMG_IN + row*IM_WIDTH, in_msg + sizeof(uint32_t), IM_WIDTH*sizeof(pix_t));
|
||||
adjust_row(row);
|
||||
}
|
||||
if(row == IM_HEIGHT-1){
|
||||
refresh = 1;
|
||||
}
|
||||
|
||||
return NO_ERR;
|
||||
}
|
||||
|
||||
int main (int argc, char** argv){
|
||||
M_REQUIRE(argc==2,"Invalid usage of client. You should pass the address of the server.\n");
|
||||
|
||||
fprintf(stderr, "Starting Caca\n");
|
||||
M_REQUIRE_NO_ERR(setup_caca(),"Error: Creating Caca\n");
|
||||
memset(IMG_IN,0,IM_TOTAL*sizeof(pix_t));
|
||||
M_REQUIRE_NO_ERR(caca_dither_bitmap(cv,0,0,IM_WIDTH,IM_HEIGHT,dither,IMG_IN), "Error: Unable to draw\n");
|
||||
caca_refresh_display(dp);
|
||||
fprintf(stderr, "Started CACA HEAT VIEWER successfully\n");
|
||||
|
||||
fprintf(stderr, "Starting Network\n");
|
||||
int32_t s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
M_REQUIRE(s > 0, "Error: Unable to open socket\n");
|
||||
M_REQUIRE_NO_ERR(bind_server(s, 0), "Error: Unable to bind socket\n");
|
||||
saddr_t srv_addr;
|
||||
M_REQUIRE_NO_ERR(get_server_addr(argv[1], DEFAULT_PORT, &srv_addr), "Error: Unable to get server adress\n");
|
||||
fprintf(stderr, "Started Network\n");
|
||||
|
||||
fprintf(stderr, "Sending poke to server...\n");
|
||||
char e = 0;
|
||||
M_REQUIRE(sendto(s,&e,0,0,(struct sockaddr *)&srv_addr,sizeof(srv_addr))==0, " Error: Unable to send message to server\n");
|
||||
fprintf(stderr, "Sent poke successfully\n");
|
||||
uint8_t quit = 0;
|
||||
while(!feof(stdin) && !ferror(stdin) && !quit){
|
||||
caca_event_t ev;
|
||||
if(caca_get_event(dp, CACA_EVENT_RESIZE | CACA_EVENT_QUIT | CACA_EVENT_KEY_PRESS, &ev, 0)){
|
||||
if(caca_get_event_type(&ev) == CACA_EVENT_RESIZE){
|
||||
caca_set_canvas_size(cv,IM_WIDTH,IM_HEIGHT);
|
||||
}else if(caca_get_event_type(&ev) & CACA_EVENT_QUIT){
|
||||
quit = 1;
|
||||
}else {
|
||||
switch(caca_get_event_key_ch(&ev)){
|
||||
case 'Q':
|
||||
case 'q':
|
||||
quit=1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint8_t in_msg[PCKT_SIZE] = {0};
|
||||
ssize_t in_msg_len = recv(s, in_msg, PCKT_SIZE, 0);
|
||||
M_REQUIRE_NO_ERR(handle_message(in_msg_len, in_msg), "Error: Couldn't handle message\n");
|
||||
++msg_cnt;
|
||||
if (msg_cnt%(IM_HEIGHT/REF_DIV)==0 || refresh){
|
||||
refresh = 0;
|
||||
msg_cnt = 0;
|
||||
M_REQUIRE_NO_ERR(caca_dither_bitmap(cv,0,0,IM_WIDTH,IM_HEIGHT,dither,IMG_IN), "Error: Unable to draw\n");
|
||||
caca_refresh_display(dp);
|
||||
}
|
||||
}
|
||||
M_REQUIRE(sendto(s,&e,0,0,(struct sockaddr *)&srv_addr,sizeof(srv_addr))==0, " Error: Unable to send message to server\n");
|
||||
M_REQUIRE_NO_ERR(clear_caca(),"Error: Clearing Caca\n" );
|
||||
close(s);
|
||||
|
||||
return NO_ERR;
|
||||
}
|
67
cs309-psoc/lab_4_1/sw/hps/application/hps_soc_system.h
Normal file
67
cs309-psoc/lab_4_1/sw/hps/application/hps_soc_system.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef _ALTERA_HPS_SOC_SYSTEM_H_
|
||||
#define _ALTERA_HPS_SOC_SYSTEM_H_
|
||||
|
||||
/*
|
||||
* This file was automatically generated by the swinfo2header utility.
|
||||
*
|
||||
* Created from SOPC Builder system 'soc_system' in
|
||||
* file 'hw/quartus/soc_system.sopcinfo'.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains macros for module 'hps_0' and devices
|
||||
* connected to the following master:
|
||||
* h2f_lw_axi_master
|
||||
*
|
||||
* Do not include this header file and another header file created for a
|
||||
* different module or master group at the same time.
|
||||
* Doing so may result in duplicate macro names.
|
||||
* Instead, use the system header file which has macros with unique names.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Macros for device 'lepton_0', class 'lepton'
|
||||
* The macros are prefixed with 'LEPTON_0_'.
|
||||
* The prefix is the slave descriptor.
|
||||
*/
|
||||
#define LEPTON_0_COMPONENT_TYPE lepton
|
||||
#define LEPTON_0_COMPONENT_NAME lepton_0
|
||||
#define LEPTON_0_BASE 0x40000
|
||||
#define LEPTON_0_SPAN 32768
|
||||
#define LEPTON_0_END 0x47fff
|
||||
|
||||
/*
|
||||
* Macros for device 'mcp3204_0', class 'mcp3204'
|
||||
* The macros are prefixed with 'MCP3204_0_'.
|
||||
* The prefix is the slave descriptor.
|
||||
*/
|
||||
#define MCP3204_0_COMPONENT_TYPE mcp3204
|
||||
#define MCP3204_0_COMPONENT_NAME mcp3204_0
|
||||
#define MCP3204_0_BASE 0x49000
|
||||
#define MCP3204_0_SPAN 16
|
||||
#define MCP3204_0_END 0x4900f
|
||||
|
||||
/*
|
||||
* Macros for device 'pwm_1', class 'pwm'
|
||||
* The macros are prefixed with 'PWM_1_'.
|
||||
* The prefix is the slave descriptor.
|
||||
*/
|
||||
#define PWM_1_COMPONENT_TYPE pwm
|
||||
#define PWM_1_COMPONENT_NAME pwm_1
|
||||
#define PWM_1_BASE 0x49010
|
||||
#define PWM_1_SPAN 16
|
||||
#define PWM_1_END 0x4901f
|
||||
|
||||
/*
|
||||
* Macros for device 'pwm_0', class 'pwm'
|
||||
* The macros are prefixed with 'PWM_0_'.
|
||||
* The prefix is the slave descriptor.
|
||||
*/
|
||||
#define PWM_0_COMPONENT_TYPE pwm
|
||||
#define PWM_0_COMPONENT_NAME pwm_0
|
||||
#define PWM_0_BASE 0x49020
|
||||
#define PWM_0_SPAN 16
|
||||
#define PWM_0_END 0x4902f
|
||||
|
||||
|
||||
#endif /* _ALTERA_HPS_SOC_SYSTEM_H_ */
|
24
cs309-psoc/lab_4_1/sw/hps/application/iorw.h
Normal file
24
cs309-psoc/lab_4_1/sw/hps/application/iorw.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __IORW_H__
|
||||
#define __IORW_H__
|
||||
|
||||
#if defined(__nios2_arch__) // For the soft-core Nios processor
|
||||
#include <io.h>
|
||||
|
||||
#define io_write_8(base, ofst, data) (IOWR_8DIRECT((base), (ofst), (data)))
|
||||
#define io_write_16(base, ofst, data) (IOWR_16DIRECT((base), (ofst), (data)))
|
||||
#define io_write_32(base, ofst, data) (IOWR_32DIRECT((base), (ofst), (data)))
|
||||
#define io_read_8(base, ofst) (IORD_8DIRECT((base), (ofst)))
|
||||
#define io_read_16(base, ofst) (IORD_16DIRECT((base), (ofst)))
|
||||
#define io_read_32(base, ofst) (IORD_32DIRECT((base), (ofst)))
|
||||
#else // For the hard-core ARM Cortex A9 processor
|
||||
#include <socal/socal.h>
|
||||
|
||||
#define io_write_8(base, ofst, data) (alt_write_byte((uintptr_t) (base) + (ofst), (data)))
|
||||
#define io_write_16(base, ofst, data) (alt_write_hword((uintptr_t) (base) + (ofst), (data)))
|
||||
#define io_write_32(base, ofst, data) (alt_write_word((uintptr_t) (base) + (ofst), (data)))
|
||||
#define io_read_8(base, ofst) (alt_read_byte((uintptr_t) (base) + (ofst)))
|
||||
#define io_read_16(base, ofst) (alt_read_hword((uintptr_t) (base) + (ofst)))
|
||||
#define io_read_32(base, ofst) (alt_read_word((uintptr_t) (base) + (ofst)))
|
||||
#endif
|
||||
|
||||
#endif
|
9
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/Makefile
Normal file
9
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
all: app
|
||||
clean:
|
||||
rm -rf *.o
|
||||
rm -f app
|
||||
|
||||
server.o: server.c server.h
|
||||
app.o: app.c server.h
|
||||
app: app.o server.o
|
125
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/app.c
Normal file
125
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/app.c
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "hps_soc_system.h"
|
||||
#include "lepton/lepton.h"
|
||||
#include "server.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <socal/hps.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
|
||||
/** The port on which the server is available */
|
||||
#define SERVER_PORT 25700
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Copy the old terminal configuration to restore it later
|
||||
struct termios orig_term_attr, new_term_attr;
|
||||
tcgetattr(fileno(stdin), &orig_term_attr);
|
||||
memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios));
|
||||
|
||||
|
||||
// Set the input to non-canonical mode, so that the keypresses are instantaneously recorded
|
||||
new_term_attr.c_lflag &= ~(ECHO | ICANON);
|
||||
new_term_attr.c_cc[VTIME] = 0;
|
||||
new_term_attr.c_cc[VMIN] = 0;
|
||||
tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);
|
||||
|
||||
// Open the physical memory through the filesystem
|
||||
int mem_fd = open("/dev/mem", O_SYNC | O_RDWR);
|
||||
if(mem_fd == -1){
|
||||
fprintf(stderr, "Failed to open /dev/mem. Exiting. Consider running this program with root privileges.\n");
|
||||
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Map the physical memory into the virtual address space
|
||||
size_t length = ALT_LWFPGASLVS_UB_ADDR - ALT_LWFPGASLVS_LB_ADDR + 1;
|
||||
size_t offset = ALT_LWFPGASLVS_OFST;
|
||||
void* mapped = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, offset);
|
||||
if (mapped == MAP_FAILED){
|
||||
fprintf(stderr, "Failed to map physical memory into virtual address space. Exiting.\n");
|
||||
close(mem_fd);
|
||||
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initialize the lepton device with the mapped memory
|
||||
lepton_dev lepton = lepton_inst(mapped + LEPTON_0_BASE);
|
||||
lepton_init(&lepton);
|
||||
|
||||
// Create the socket
|
||||
printf("Creating and binding a UDP socket on port %d...\n", SERVER_PORT);
|
||||
int socket = create_upd_socket(SERVER_PORT);
|
||||
if (socket == -1) {
|
||||
fprintf(stderr, "Failed to create the UDP socket. Exiting.\n");
|
||||
close(mem_fd);
|
||||
munmap(mapped, length);
|
||||
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Socket successfully bound.\n");
|
||||
printf("Press 'q' to stop the server.\n");
|
||||
|
||||
while (1) {
|
||||
// Wait for a client to connect
|
||||
printf("Waiting for a new client to connect...\n");
|
||||
struct sockaddr_in client_addr, sender_addr;
|
||||
int event;
|
||||
|
||||
do {
|
||||
// Wait for either a packet or the user quiting
|
||||
event = wait_for_event(socket, &client_addr, -1);
|
||||
} while (event == NO_EVENT);
|
||||
|
||||
if (event == QUIT_EVENT) {
|
||||
printf("Stopping the server...\n");
|
||||
munmap(mapped, length);
|
||||
close(mem_fd);
|
||||
close(socket);
|
||||
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Inform the user about the connection
|
||||
char addr_string[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &client_addr.sin_addr, addr_string, INET_ADDRSTRLEN);
|
||||
printf("Connected to client at address %s:%d.\n", addr_string, client_addr.sin_port);
|
||||
|
||||
// We continuously send the stream to the client until stopping is requested
|
||||
do {
|
||||
do {
|
||||
lepton_start_capture(&lepton);
|
||||
lepton_wait_until_eof(&lepton);
|
||||
} while (lepton_error_check(&lepton));
|
||||
|
||||
uint16_t* image = lepton_get_image(&lepton, true);
|
||||
send_image(socket, image, &client_addr);
|
||||
|
||||
event = wait_for_event(socket, &sender_addr, 0);
|
||||
if (event == PACKET_EVENT &&
|
||||
(sender_addr.sin_addr.s_addr != client_addr.sin_addr.s_addr
|
||||
|| sender_addr.sin_port != client_addr.sin_port))
|
||||
event = NO_EVENT;
|
||||
} while (event == NO_EVENT);
|
||||
|
||||
// Stop the server if the user wants to
|
||||
if (event == QUIT_EVENT) {
|
||||
printf("Stopping the server...\n");
|
||||
munmap(mapped, length);
|
||||
close(mem_fd);
|
||||
close(socket);
|
||||
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
printf("The client disconnected.\n");
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
#include "joysticks.h"
|
||||
|
||||
#define JOYSTICK_RIGHT_VRY_MCP3204_CHANNEL (0)
|
||||
#define JOYSTICK_RIGHT_VRX_MCP3204_CHANNEL (1)
|
||||
#define JOYSTICK_LEFT_VRY_MCP3204_CHANNEL (2)
|
||||
#define JOYSTICK_LEFT_VRX_MCP3204_CHANNEL (3)
|
||||
|
||||
/**
|
||||
* joysticks_inst
|
||||
*
|
||||
* Instantiate a joysticks device structure.
|
||||
*
|
||||
* @param base Base address of the MCP3204 component connected to the joysticks.
|
||||
*/
|
||||
joysticks_dev joysticks_inst(void *mcp3204_base) {
|
||||
joysticks_dev dev;
|
||||
dev.mcp3204 = mcp3204_inst((void *) mcp3204_base);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_init
|
||||
*
|
||||
* Initializes the joysticks device.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
void joysticks_init(joysticks_dev *dev) {
|
||||
mcp3204_init(&(dev->mcp3204));
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_read_left_vertical
|
||||
*
|
||||
* Returns the vertical position of the left joystick. Return value ranges
|
||||
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
uint32_t joysticks_read_left_vertical(joysticks_dev *dev) {
|
||||
return JOYSTICKS_MAX_VALUE - mcp3204_read(&dev->mcp3204, JOYSTICK_RIGHT_VRY_MCP3204_CHANNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_read_left_horizontal
|
||||
*
|
||||
* Returns the horizontal position of the left joystick. Return value ranges
|
||||
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
uint32_t joysticks_read_left_horizontal(joysticks_dev *dev) {
|
||||
return mcp3204_read(&dev->mcp3204, JOYSTICK_LEFT_VRX_MCP3204_CHANNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_read_right_vertical
|
||||
*
|
||||
* Returns the vertical position of the right joystick. Return value ranges
|
||||
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
uint32_t joysticks_read_right_vertical(joysticks_dev *dev) {
|
||||
return JOYSTICKS_MAX_VALUE - mcp3204_read(&dev->mcp3204, JOYSTICK_RIGHT_VRY_MCP3204_CHANNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* joysticks_read_right_horizontal
|
||||
*
|
||||
* Returns the horizontal position of the left joystick. Return value ranges
|
||||
* between JOYSTICKS_MIN_VALUE and JOYSTICKS_MAX_VALUE.
|
||||
*
|
||||
* @param dev joysticks device structure.
|
||||
*/
|
||||
uint32_t joysticks_read_right_horizontal(joysticks_dev *dev) {
|
||||
return mcp3204_read(&dev->mcp3204, JOYSTICK_RIGHT_VRX_MCP3204_CHANNEL);
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
#ifndef __JOYSTICKS_H__
|
||||
#define __JOYSTICKS_H__
|
||||
|
||||
#include "mcp3204/mcp3204.h"
|
||||
|
||||
/* joysticks device structure */
|
||||
typedef struct joysticks_dev {
|
||||
mcp3204_dev mcp3204; /* MCP3204 device handle */
|
||||
} joysticks_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
#define JOYSTICKS_MIN_VALUE (MCP3204_MIN_VALUE)
|
||||
#define JOYSTICKS_MAX_VALUE (MCP3204_MAX_VALUE)
|
||||
|
||||
joysticks_dev joysticks_inst(void *mcp3204_base);
|
||||
|
||||
void joysticks_init(joysticks_dev *dev);
|
||||
|
||||
uint32_t joysticks_read_left_vertical(joysticks_dev *dev);
|
||||
uint32_t joysticks_read_left_horizontal(joysticks_dev *dev);
|
||||
uint32_t joysticks_read_right_vertical(joysticks_dev *dev);
|
||||
uint32_t joysticks_read_right_horizontal(joysticks_dev *dev);
|
||||
|
||||
#endif /* __JOYSTICKS_H__ */
|
@@ -0,0 +1,44 @@
|
||||
#include "mcp3204.h"
|
||||
#include "iorw.h"
|
||||
|
||||
#define MCP3204_NUM_CHANNELS (4)
|
||||
|
||||
/**
|
||||
* mcp3204_inst
|
||||
*
|
||||
* Instantiate a mcp3204 device structure.
|
||||
*
|
||||
* @param base Base address of the component.
|
||||
*/
|
||||
mcp3204_dev mcp3204_inst(void *base) {
|
||||
mcp3204_dev dev;
|
||||
dev.base = base;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcp3204_init
|
||||
*
|
||||
* Initializes the mcp3204 device.
|
||||
*
|
||||
* @param dev mcp3204 device structure.
|
||||
*/
|
||||
void mcp3204_init(mcp3204_dev *dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcp3204_read
|
||||
*
|
||||
* Reads the register corresponding to the supplied channel parameter.
|
||||
*
|
||||
* @param dev mcp3204 device structure.
|
||||
* @param channel channel to be read
|
||||
*/
|
||||
uint32_t mcp3204_read(mcp3204_dev *dev, uint32_t channel) {
|
||||
if (channel >= 4)
|
||||
return 0;
|
||||
|
||||
return io_read_32(dev->base, channel * 4);
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
#ifndef __MCP3204_H__
|
||||
#define __MCP3204_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* mcp3204 device structure */
|
||||
typedef struct mcp3204_dev {
|
||||
void *base; /* Base address of component */
|
||||
} mcp3204_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
#define MCP3204_MIN_VALUE (0)
|
||||
#define MCP3204_MAX_VALUE (4095)
|
||||
|
||||
mcp3204_dev mcp3204_inst(void *base);
|
||||
|
||||
void mcp3204_init(mcp3204_dev *dev);
|
||||
uint32_t mcp3204_read(mcp3204_dev *dev, uint32_t channel);
|
||||
|
||||
#endif /* __MCP3204_H__ */
|
@@ -0,0 +1,9 @@
|
||||
#ifndef __MCP3204_REGS_H__
|
||||
#define __MCP3204_REGS_H__
|
||||
|
||||
#define MCP3204_CHANNEL_0_OFST (0 * 4) /* RO */
|
||||
#define MCP3204_CHANNEL_1_OFST (1 * 4) /* RO */
|
||||
#define MCP3204_CHANNEL_2_OFST (2 * 4) /* RO */
|
||||
#define MCP3204_CHANNEL_3_OFST (3 * 4) /* RO */
|
||||
|
||||
#endif /* __MCP3204_REGS_H__ */
|
122
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/lepton/lepton.c
Normal file
122
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/lepton/lepton.c
Normal file
@@ -0,0 +1,122 @@
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lepton_regs.h"
|
||||
#include "lepton.h"
|
||||
#include "iorw.h"
|
||||
|
||||
/**
|
||||
* lepton_inst
|
||||
*
|
||||
* Instantiate a lepton device structure.
|
||||
*
|
||||
* @param base Base address of the component.
|
||||
*/
|
||||
lepton_dev lepton_inst(void *base) {
|
||||
lepton_dev dev;
|
||||
dev.base = base;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_init
|
||||
*
|
||||
* Initializes the lepton device.
|
||||
*
|
||||
* @param dev lepton device structure.
|
||||
*/
|
||||
void lepton_init(lepton_dev *dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_start_capture
|
||||
*
|
||||
* Instructs the device to start the frame capture process.
|
||||
*
|
||||
* @param dev lepton device structure.
|
||||
*/
|
||||
void lepton_start_capture(lepton_dev *dev) {
|
||||
io_write_16(dev->base, LEPTON_REGS_COMMAND_OFST, 0x1);
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_error_check
|
||||
*
|
||||
* @abstract Check for errors at the device level.
|
||||
* @param dev lepton device structure.
|
||||
* @return true if there was an error, and false otherwise.
|
||||
*/
|
||||
bool lepton_error_check(lepton_dev *dev) {
|
||||
return (io_read_16(dev->base, LEPTON_REGS_STATUS_OFST) & 0x2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_wait_until_eof
|
||||
*
|
||||
* Waits until the frame being captured has been fully received and saved in the
|
||||
* internal memory.
|
||||
*
|
||||
* @param dev lepton device structure.
|
||||
*/
|
||||
void lepton_wait_until_eof(lepton_dev *dev) {
|
||||
while (io_read_16(dev->base, LEPTON_REGS_STATUS_OFST) & 0x1);
|
||||
}
|
||||
|
||||
/**
|
||||
* lepton_save_capture
|
||||
*
|
||||
* Saves the captured frame on the host filesystem under the supplied filename.
|
||||
* The frame will be saved in PGM format.
|
||||
*
|
||||
* @param dev lepton device structure.
|
||||
* @param adjusted Setting this parameter to false will cause RAW sensor data to
|
||||
* be written to the file.
|
||||
* Setting this parameter to true will cause a preprocessed image
|
||||
* (with a stretched dynamic range) to be saved to the file.
|
||||
*
|
||||
* @param fname the output file name.
|
||||
*/
|
||||
void lepton_save_capture(lepton_dev *dev, bool adjusted, FILE* file) {
|
||||
assert(file);
|
||||
|
||||
const uint8_t num_rows = 60;
|
||||
const uint8_t num_cols = 80;
|
||||
|
||||
uint16_t offset = LEPTON_REGS_RAW_BUFFER_OFST;
|
||||
uint16_t max_value = io_read_16(dev->base, LEPTON_REGS_MAX_OFST);
|
||||
if (adjusted) {
|
||||
offset = LEPTON_REGS_ADJUSTED_BUFFER_OFST;
|
||||
max_value = 0x3fff;
|
||||
}
|
||||
|
||||
/* Write PGM header */
|
||||
fprintf(file, "P2\n%" PRIu8 " %" PRIu8 "\n%" PRIu16, num_cols, num_rows, max_value);
|
||||
|
||||
/* Write body */
|
||||
uint8_t row = 0;
|
||||
for (row = 0; row < num_rows; ++row) {
|
||||
fprintf(file, "\n");
|
||||
|
||||
uint8_t col = 0;
|
||||
for (col = 0; col < num_cols; ++col) {
|
||||
if (col > 0) {
|
||||
fprintf(file, " ");
|
||||
}
|
||||
|
||||
uint16_t current_ofst = offset + (row * num_cols + col) * sizeof(uint16_t);
|
||||
uint16_t pix_value = io_read_16(dev->base, current_ofst);
|
||||
fprintf(file, "%" PRIu16, pix_value);
|
||||
}
|
||||
}
|
||||
|
||||
assert(!fclose(file));
|
||||
}
|
||||
|
||||
uint16_t* lepton_get_image(lepton_dev *dev, bool adjusted) {
|
||||
size_t offset = adjusted ? LEPTON_REGS_ADJUSTED_BUFFER_OFST : LEPTON_REGS_RAW_BUFFER_OFST;
|
||||
return (uint16_t*) ((uint8_t*) dev->base + offset);
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
#ifndef __LEPTON_H__
|
||||
#define __LEPTON_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* lepton device structure */
|
||||
typedef struct {
|
||||
void *base; /* Base address of the component */
|
||||
} lepton_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
lepton_dev lepton_inst(void *base);
|
||||
|
||||
void lepton_init(lepton_dev *dev);
|
||||
void lepton_start_capture(lepton_dev *dev);
|
||||
void lepton_wait_until_eof(lepton_dev *dev);
|
||||
bool lepton_error_check(lepton_dev *dev);
|
||||
void lepton_save_capture(lepton_dev *dev, bool adjusted, FILE* file);
|
||||
uint16_t* lepton_get_image(lepton_dev *dev, bool adjusted);
|
||||
|
||||
#endif /* __LEPTON_H__ */
|
@@ -0,0 +1,25 @@
|
||||
#ifndef __LEPTON_REGS_H__
|
||||
#define __LEPTON_REGS_H__
|
||||
|
||||
/* Register offsets */
|
||||
#define LEPTON_REGS_COMMAND_OFST ( 0 * 2) /* WO */
|
||||
#define LEPTON_REGS_STATUS_OFST ( 1 * 2) /* RO */
|
||||
#define LEPTON_REGS_MIN_OFST ( 2 * 2) /* RO */
|
||||
#define LEPTON_REGS_MAX_OFST ( 3 * 2) /* RO */
|
||||
#define LEPTON_REGS_SUM_LSB_OFST ( 4 * 2) /* RO */
|
||||
#define LEPTON_REGS_SUM_MSB_OFST ( 5 * 2) /* RO */
|
||||
#define LEPTON_REGS_ROW_IDX_OFST ( 6 * 2) /* RO */
|
||||
#define LEPTON_REGS_RAW_BUFFER_OFST ( 8 * 2) /* RO */
|
||||
#define LEPTON_REGS_ADJUSTED_BUFFER_OFST (8192 * 2) /* RO */
|
||||
|
||||
/* Command register */
|
||||
#define LEPTON_COMMAND_START (0x0001)
|
||||
|
||||
/* Status register */
|
||||
#define LEPTON_STATUS_CAPTURE_IN_PROGRESS_MASK (1 << 0)
|
||||
#define LEPTON_STATUS_ERROR_MASK (1 << 1)
|
||||
|
||||
#define LEPTON_REGS_BUFFER_NUM_PIXELS (80 * 60)
|
||||
#define LEPTON_REGS_BUFFER_BYTELENGTH (LEPTON_REGS_BUFFER_NUM_PIXELS * 2)
|
||||
|
||||
#endif /* __LEPTON_REGS_H__ */
|
109
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/pantilt/pantilt.c
Normal file
109
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/pantilt/pantilt.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "pantilt.h"
|
||||
|
||||
/**
|
||||
* pantilt_inst
|
||||
*
|
||||
* Instantiate a pantilt device structure.
|
||||
*
|
||||
* @param pwm_v_base Base address of the vertical PWM component.
|
||||
* @param pwm_h_base Base address of the horizontal PWM component.
|
||||
*/
|
||||
pantilt_dev pantilt_inst(void *pwm_v_base, void *pwm_h_base) {
|
||||
pantilt_dev dev;
|
||||
dev.pwm_v = pwm_inst(pwm_v_base);
|
||||
dev.pwm_h = pwm_inst(pwm_h_base);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_init
|
||||
*
|
||||
* Initializes the pantilt device.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_init(pantilt_dev *dev) {
|
||||
pwm_init(&(dev->pwm_v));
|
||||
pwm_init(&(dev->pwm_h));
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_configure_vertical
|
||||
*
|
||||
* Configure the vertical PWM component.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
* @param duty_cycle pwm duty cycle in us.
|
||||
*/
|
||||
void pantilt_configure_vertical(pantilt_dev *dev, uint32_t duty_cycle) {
|
||||
// Need to compensate for inverted servo rotation.
|
||||
duty_cycle = PANTILT_PWM_V_MAX_DUTY_CYCLE_US - duty_cycle + PANTILT_PWM_V_MIN_DUTY_CYCLE_US;
|
||||
|
||||
pwm_configure(&(dev->pwm_v),
|
||||
duty_cycle,
|
||||
PANTILT_PWM_PERIOD_US,
|
||||
PANTILT_PWM_CLOCK_FREQ_HZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_configure_horizontal
|
||||
*
|
||||
* Configure the horizontal PWM component.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
* @param duty_cycle pwm duty cycle in us.
|
||||
*/
|
||||
void pantilt_configure_horizontal(pantilt_dev *dev, uint32_t duty_cycle) {
|
||||
// Need to compensate for inverted servo rotation.
|
||||
duty_cycle = PANTILT_PWM_H_MAX_DUTY_CYCLE_US - duty_cycle + PANTILT_PWM_H_MIN_DUTY_CYCLE_US;
|
||||
|
||||
pwm_configure(&(dev->pwm_h),
|
||||
duty_cycle,
|
||||
PANTILT_PWM_PERIOD_US,
|
||||
PANTILT_PWM_CLOCK_FREQ_HZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_start_vertical
|
||||
*
|
||||
* Starts the vertical pwm controller.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_start_vertical(pantilt_dev *dev) {
|
||||
pwm_start(&(dev->pwm_v));
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_start_horizontal
|
||||
*
|
||||
* Starts the horizontal pwm controller.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_start_horizontal(pantilt_dev *dev) {
|
||||
pwm_start(&(dev->pwm_h));
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_stop_vertical
|
||||
*
|
||||
* Stops the vertical pwm controller.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_stop_vertical(pantilt_dev *dev) {
|
||||
pwm_stop(&(dev->pwm_v));
|
||||
}
|
||||
|
||||
/**
|
||||
* pantilt_stop_horizontal
|
||||
*
|
||||
* Stops the horizontal pwm controller.
|
||||
*
|
||||
* @param dev pantilt device structure.
|
||||
*/
|
||||
void pantilt_stop_horizontal(pantilt_dev *dev) {
|
||||
pwm_stop(&(dev->pwm_h));
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
#ifndef __PANTILT_H__
|
||||
#define __PANTILT_H__
|
||||
|
||||
#include "pwm/pwm.h"
|
||||
|
||||
/* joysticks device structure */
|
||||
typedef struct pantilt_dev {
|
||||
pwm_dev pwm_v; /* Vertical PWM device handle */
|
||||
pwm_dev pwm_h; /* Horizontal PWM device handle */
|
||||
} pantilt_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
#define PANTILT_PWM_CLOCK_FREQ_HZ (50000000) // 50.00 MHz
|
||||
|
||||
#define PANTILT_PWM_PERIOD_US (25000) // 25.00 ms
|
||||
|
||||
/* Vertical servo */
|
||||
#define PANTILT_PWM_V_MIN_DUTY_CYCLE_US (950) // 0.95 ms
|
||||
#define PANTILT_PWM_V_MAX_DUTY_CYCLE_US (2150) // 2.15 ms
|
||||
|
||||
/* Horizontal servo */
|
||||
#define PANTILT_PWM_H_MIN_DUTY_CYCLE_US (1000) // 1.00 ms
|
||||
#define PANTILT_PWM_H_MAX_DUTY_CYCLE_US (2000) // 2.00 ms
|
||||
|
||||
pantilt_dev pantilt_inst(void *pwm_v_base, void *pwm_h_base);
|
||||
|
||||
void pantilt_init(pantilt_dev *dev);
|
||||
|
||||
void pantilt_configure_vertical(pantilt_dev *dev, uint32_t duty_cycle);
|
||||
void pantilt_configure_horizontal(pantilt_dev *dev, uint32_t duty_cycle);
|
||||
void pantilt_start_vertical(pantilt_dev *dev);
|
||||
void pantilt_start_horizontal(pantilt_dev *dev);
|
||||
void pantilt_stop_vertical(pantilt_dev *dev);
|
||||
void pantilt_stop_horizontal(pantilt_dev *dev);
|
||||
|
||||
#endif /* __PANTILT_H__ */
|
@@ -0,0 +1,68 @@
|
||||
#include "pwm.h"
|
||||
#include "pwm_regs.h"
|
||||
#include "iorw.h"
|
||||
|
||||
#define MICROSEC_TO_CLK(time, freq) ((time) * ((freq) / 1000000))
|
||||
|
||||
/**
|
||||
* pwm_inst
|
||||
*
|
||||
* Instantiate a pwm device structure.
|
||||
*
|
||||
* @param base Base address of the component.
|
||||
*/
|
||||
pwm_dev pwm_inst(void *base) {
|
||||
pwm_dev dev;
|
||||
|
||||
dev.base = base;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* pwm_init
|
||||
*
|
||||
* Initializes the pwm device. This function stops the controller.
|
||||
*
|
||||
* @param dev pwm device structure.
|
||||
*/
|
||||
void pwm_init(pwm_dev *dev) {
|
||||
pwm_stop(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* pwm_configure
|
||||
*
|
||||
* Configure pwm component.
|
||||
*
|
||||
* @param dev pwm device structure.
|
||||
* @param duty_cycle pwm duty cycle in us.
|
||||
* @param period pwm period in us.
|
||||
* @param module_frequency frequency at which the component is clocked.
|
||||
*/
|
||||
void pwm_configure(pwm_dev *dev, uint32_t duty_cycle, uint32_t period, uint32_t module_frequency) {
|
||||
io_write_32(dev->base, PWM_PERIOD_OFST, MICROSEC_TO_CLK(period, module_frequency));
|
||||
io_write_32(dev->base, PWM_DUTY_CYCLE_OFST, MICROSEC_TO_CLK(duty_cycle, module_frequency));
|
||||
}
|
||||
|
||||
/**
|
||||
* pwm_start
|
||||
*
|
||||
* Starts the pwm controller.
|
||||
*
|
||||
* @param dev pwm device structure.
|
||||
*/
|
||||
void pwm_start(pwm_dev *dev) {
|
||||
io_write_32(dev->base, PWM_CTRL_OFST, PWM_CTRL_START_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* pwm_stop
|
||||
*
|
||||
* Stops the pwm controller.
|
||||
*
|
||||
* @param dev pwm device structure.
|
||||
*/
|
||||
void pwm_stop(pwm_dev *dev) {
|
||||
io_write_32(dev->base, PWM_CTRL_OFST, PWM_CTRL_START_MASK);
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
#ifndef __PWM_H__
|
||||
#define __PWM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* pwm device structure */
|
||||
typedef struct pwm_dev {
|
||||
void *base; /* Base address of component */
|
||||
} pwm_dev;
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
pwm_dev pwm_inst(void *base);
|
||||
|
||||
void pwm_init(pwm_dev *dev);
|
||||
void pwm_configure(pwm_dev *dev, uint32_t duty_cycle, uint32_t period, uint32_t module_frequency);
|
||||
void pwm_start(pwm_dev *dev);
|
||||
void pwm_stop(pwm_dev *dev);
|
||||
|
||||
#endif /* __PWM_H__ */
|
@@ -0,0 +1,11 @@
|
||||
#ifndef __PWM_REGS_H__
|
||||
#define __PWM_REGS_H__
|
||||
|
||||
#define PWM_PERIOD_OFST (0 * 4) /* RW */
|
||||
#define PWM_DUTY_CYCLE_OFST (1 * 4) /* RW */
|
||||
#define PWM_CTRL_OFST (2 * 4) /* WO */
|
||||
|
||||
#define PWM_CTRL_STOP_MASK (0)
|
||||
#define PWM_CTRL_START_MASK (1)
|
||||
|
||||
#endif /* __PWM_REGS_H__ */
|
79
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/server.c
Normal file
79
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/server.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "server.h"
|
||||
#include <sys/socket.h> // for socket
|
||||
#include <sys/types.h> // for AF_INET
|
||||
#include <netinet/in.h> // for sockaddr_in
|
||||
#include <arpa/inet.h> // for htonl
|
||||
#include <stdint.h> // for uint16_t
|
||||
#include <unistd.h> // for close
|
||||
#include <string.h> // for memcpy
|
||||
#include <poll.h> // for poll
|
||||
|
||||
#define ROW_SIZE (IMG_WIDTH * sizeof(uint16_t))
|
||||
|
||||
int create_upd_socket(uint16_t port) {
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (sock == -1)
|
||||
return -1;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr))) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int wait_for_event(int socket, struct sockaddr_in* addr, int timeout) {
|
||||
char c = 0;
|
||||
struct pollfd fds[2];
|
||||
|
||||
// Wait for a packet
|
||||
fds[0].fd = socket;
|
||||
fds[0].events = POLLIN;
|
||||
fds[0].revents = 0;
|
||||
|
||||
// Wait for a command line input
|
||||
fds[1].fd = STDIN_FILENO;
|
||||
fds[1].events = POLLIN;
|
||||
fds[1].revents = 0;
|
||||
|
||||
// Wait for the two file descriptors in parallel
|
||||
int ret = poll(fds, 2, timeout);
|
||||
|
||||
if (ret <= 0) // error or timeout
|
||||
return NO_EVENT;
|
||||
|
||||
if (fds[1].revents & POLLIN) {
|
||||
read(STDIN_FILENO, &c, 1);
|
||||
|
||||
if (c == 'q')
|
||||
return QUIT_EVENT;
|
||||
}
|
||||
|
||||
if (fds[0].revents & POLLIN) {
|
||||
socklen_t addr_len = sizeof(struct sockaddr_in);
|
||||
recvfrom(socket, &c, 1, 0, (struct sockaddr*) addr, &addr_len);
|
||||
return PACKET_EVENT;
|
||||
}
|
||||
|
||||
return NO_EVENT;
|
||||
}
|
||||
|
||||
void send_image(int socket, uint16_t* img, const struct sockaddr_in* addr) {
|
||||
// This buffer is used to hold the packet for a row
|
||||
char row_buffer[sizeof(uint32_t) + ROW_SIZE];
|
||||
|
||||
// We send the rows one by one
|
||||
uint8_t i = 0;
|
||||
for (i = 0; i < IMG_HEIGHT; i++) {
|
||||
*((uint32_t*) row_buffer) = i; // The first bytes of the packet contain the row index
|
||||
memcpy(row_buffer + sizeof(uint32_t), img + i * IMG_WIDTH, ROW_SIZE); // The rest contains the actual row
|
||||
sendto(socket, row_buffer, sizeof(uint32_t) + ROW_SIZE, 0, (const struct sockaddr*) addr, sizeof(*addr));
|
||||
}
|
||||
}
|
32
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/server.h
Normal file
32
cs309-psoc/lab_4_1/sw/hps/application/lab_4_1/server.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef __SERVER_H__
|
||||
#define __SERVER_H__
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** Image definitions - needs to move to another file later */
|
||||
#define IMG_WIDTH 80
|
||||
#define IMG_HEIGHT 60
|
||||
#define IMG_SIZE (IMG_WIDTH * IMG_HEIGHT)
|
||||
|
||||
/**
|
||||
* Creates and binds a socket on the given port, using the UDP protocol.
|
||||
* If an error occured, -1 is returned, otherwise the socket is returned.
|
||||
*/
|
||||
int create_upd_socket(in_port_t port);
|
||||
|
||||
/**
|
||||
* Polls the given socket for a message, and check if the user wants to quit by pressing q
|
||||
* in the console. Returns what happened in the form of an integer.
|
||||
*/
|
||||
#define NO_EVENT 0
|
||||
#define QUIT_EVENT 1
|
||||
#define PACKET_EVENT 2
|
||||
int wait_for_event(int socket, struct sockaddr_in* addr, int timeout);
|
||||
|
||||
/**
|
||||
* Sends the entire image over udp, row by row, through the given socket.
|
||||
*/
|
||||
void send_image(int socket, uint16_t* img, const struct sockaddr_in* addr);
|
||||
|
||||
#endif
|
@@ -0,0 +1,9 @@
|
||||
|
||||
all: app
|
||||
clean:
|
||||
rm -rf *.o
|
||||
rm -f app
|
||||
|
||||
server.o: server.c server.h
|
||||
app.o: app.c server.h
|
||||
app: app.o server.o
|
94
cs309-psoc/lab_4_1/sw/hps/application/mock_server/app.c
Normal file
94
cs309-psoc/lab_4_1/sw/hps/application/mock_server/app.c
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "server.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
/** The port on which the server is available */
|
||||
#define SERVER_PORT 25700
|
||||
|
||||
// Creates a moving fake image
|
||||
void generate_image(uint16_t* img, size_t t);
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
// Set the input to non-canonical mode, so that the keypresses are instantaneously recorded
|
||||
struct termios term_attr;
|
||||
tcgetattr(fileno(stdin), &term_attr);
|
||||
term_attr.c_lflag &= ~(ECHO | ICANON);
|
||||
term_attr.c_cc[VTIME] = 0;
|
||||
term_attr.c_cc[VMIN] = 0;
|
||||
tcsetattr(fileno(stdin), TCSANOW, &term_attr);
|
||||
|
||||
// This is the image that will be sent
|
||||
uint16_t img[IMG_WIDTH * IMG_HEIGHT];
|
||||
size_t t = 0;
|
||||
|
||||
// Create the socket
|
||||
printf("Creating and binding a UDP socket on port %d...\n", SERVER_PORT);
|
||||
int socket = create_upd_socket(SERVER_PORT);
|
||||
if (socket == -1) {
|
||||
fprintf(stderr, "Failed to create the UDP socket. Exiting.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Socket successfully bound.\n");
|
||||
printf("Press 'q' to stop the server.\n");
|
||||
|
||||
while (1) {
|
||||
// Wait for a client to connect
|
||||
printf("Waiting for a new client to connect...\n");
|
||||
struct sockaddr_in client_addr, sender_addr;
|
||||
int event;
|
||||
|
||||
do {
|
||||
// Wait for either a packet or the user quiting
|
||||
event = wait_for_event(socket, &client_addr, -1);
|
||||
} while (event == NO_EVENT);
|
||||
|
||||
if (event == QUIT_EVENT) {
|
||||
printf("Stopping the server...\n");
|
||||
close(socket);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Inform the user about the connection
|
||||
char addr_string[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &client_addr.sin_addr, addr_string, INET_ADDRSTRLEN);
|
||||
printf("Connected to client at address %s:%d.\n", addr_string, client_addr.sin_port);
|
||||
|
||||
// We continuously send the stream to the client until stopping is requested
|
||||
do {
|
||||
generate_image(img, t++);
|
||||
send_image(socket, img, &client_addr);
|
||||
event = wait_for_event(socket, &sender_addr, 100);
|
||||
|
||||
if (event == PACKET_EVENT &&
|
||||
(sender_addr.sin_addr.s_addr != client_addr.sin_addr.s_addr
|
||||
|| sender_addr.sin_port != client_addr.sin_port))
|
||||
event = NO_EVENT;
|
||||
} while (event == NO_EVENT);
|
||||
|
||||
// Stop the server if the user wants to
|
||||
if (event == QUIT_EVENT) {
|
||||
printf("Stopping the server...\n");
|
||||
close(socket);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
printf("The client disconnected.\n");
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void generate_image(uint16_t* img, size_t t) {
|
||||
for (size_t x = 0; x < IMG_WIDTH; x++) {
|
||||
uint16_t val = ((x + t) % IMG_WIDTH) * 0x3FFF / IMG_WIDTH;
|
||||
|
||||
for (size_t y = 0; y < IMG_HEIGHT; y++)
|
||||
img[y * IMG_WIDTH + x] = val;
|
||||
}
|
||||
}
|
79
cs309-psoc/lab_4_1/sw/hps/application/mock_server/server.c
Normal file
79
cs309-psoc/lab_4_1/sw/hps/application/mock_server/server.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "server.h"
|
||||
#include <sys/socket.h> // for socket
|
||||
#include <sys/types.h> // for AF_INET
|
||||
#include <netinet/in.h> // for sockaddr_in
|
||||
#include <arpa/inet.h> // for htonl
|
||||
#include <stdint.h> // for uint16_t
|
||||
#include <unistd.h> // for close
|
||||
#include <string.h> // for memcpy
|
||||
#include <poll.h> // for poll
|
||||
|
||||
#define ROW_SIZE (IMG_WIDTH * sizeof(uint16_t))
|
||||
|
||||
int create_upd_socket(uint16_t port) {
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (sock == -1)
|
||||
return -1;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr))) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int wait_for_event(int socket, struct sockaddr_in* addr, int timeout) {
|
||||
char c = 0;
|
||||
struct pollfd fds[2];
|
||||
|
||||
// Wait for a packet
|
||||
fds[0].fd = socket;
|
||||
fds[0].events = POLLIN;
|
||||
fds[0].revents = 0;
|
||||
|
||||
// Wait for a command line input
|
||||
fds[1].fd = STDIN_FILENO;
|
||||
fds[1].events = POLLIN;
|
||||
fds[1].revents = 0;
|
||||
|
||||
// Wait for the two file descriptors in parallel
|
||||
int ret = poll(fds, 2, timeout);
|
||||
|
||||
if (ret <= 0) // error or timeout
|
||||
return NO_EVENT;
|
||||
|
||||
if (fds[1].revents & POLLIN) {
|
||||
read(STDIN_FILENO, &c, 1);
|
||||
|
||||
if (c == 'q')
|
||||
return QUIT_EVENT;
|
||||
}
|
||||
|
||||
if (fds[0].revents & POLLIN) {
|
||||
socklen_t addr_len = sizeof(struct sockaddr_in);
|
||||
recvfrom(socket, &c, 1, 0, (struct sockaddr*) addr, &addr_len);
|
||||
return PACKET_EVENT;
|
||||
}
|
||||
|
||||
return NO_EVENT;
|
||||
}
|
||||
|
||||
void send_image(int socket, uint16_t* img, const struct sockaddr_in* addr) {
|
||||
// This buffer is used to hold the packet for a row
|
||||
char row_buffer[sizeof(uint32_t) + ROW_SIZE];
|
||||
|
||||
// We send the rows one by one
|
||||
uint8_t i = 0;
|
||||
for (i = 0; i < IMG_HEIGHT; i++) {
|
||||
*((uint32_t*) row_buffer) = i; // The first bytes of the packet contain the row index
|
||||
memcpy(row_buffer + sizeof(uint32_t), img + i * IMG_WIDTH, ROW_SIZE); // The rest contains the actual row
|
||||
sendto(socket, row_buffer, sizeof(uint32_t) + ROW_SIZE, 0, (const struct sockaddr*) addr, sizeof(*addr));
|
||||
}
|
||||
}
|
32
cs309-psoc/lab_4_1/sw/hps/application/mock_server/server.h
Normal file
32
cs309-psoc/lab_4_1/sw/hps/application/mock_server/server.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef __SERVER_H__
|
||||
#define __SERVER_H__
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** Image definitions - needs to move to another file later */
|
||||
#define IMG_WIDTH 80
|
||||
#define IMG_HEIGHT 60
|
||||
#define IMG_SIZE (IMG_WIDTH * IMG_HEIGHT)
|
||||
|
||||
/**
|
||||
* Creates and binds a socket on the given port, using the UDP protocol.
|
||||
* If an error occured, -1 is returned, otherwise the socket is returned.
|
||||
*/
|
||||
int create_upd_socket(in_port_t port);
|
||||
|
||||
/**
|
||||
* Polls the given socket for a message, and check if the user wants to quit by pressing q
|
||||
* in the console. Returns what happened in the form of an integer.
|
||||
*/
|
||||
#define NO_EVENT 0
|
||||
#define QUIT_EVENT 1
|
||||
#define PACKET_EVENT 2
|
||||
int wait_for_event(int socket, struct sockaddr_in* addr, int timeout);
|
||||
|
||||
/**
|
||||
* Sends the entire image over udp, row by row, through the given socket.
|
||||
*/
|
||||
void send_image(int socket, uint16_t* img, const struct sockaddr_in* addr);
|
||||
|
||||
#endif
|
22
cs309-psoc/lab_4_1/sw/hps/linux/rootfs/config_post_install.sh
Executable file
22
cs309-psoc/lab_4_1/sw/hps/linux/rootfs/config_post_install.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash -x
|
||||
# apt sources
|
||||
# uncomment the "deb" lines (no need to uncomment "deb src" lines)
|
||||
|
||||
# Edit the “/etc/apt/sources.list” file to configure the package manager. This
|
||||
# file contains a list of mirrors that the package manager queries. By default,
|
||||
# this file has all fields commented out, so the package manager will not have
|
||||
# access to any mirrors. The following command uncomments all commented out
|
||||
# lines starting with "deb". These contain the mirrors we are interested in.
|
||||
sudo perl -pi -e 's/^#+\s+(deb\s+http)/$1/g' "/etc/apt/sources.list"
|
||||
|
||||
# When writing our linux applications, we want to use ARM DS-5’s remote
|
||||
# debugging feature to automatically transfer our binaries to the target device
|
||||
# and to start a debugging session. The remote debugging feature requires an SSH
|
||||
# server and a remote gdb server to be available on the target. These are easy
|
||||
# to install as we have a package manager available
|
||||
sudo apt update
|
||||
sudo apt -y install ssh gdbserver
|
||||
|
||||
# Allow root SSH login with password (needed so we can use ARM DS-5 for remote
|
||||
# debugging)
|
||||
sudo perl -pi -e 's/^(PermitRootLogin) without-password$/$1 yes/g' "/etc/ssh/sshd_config"
|
74
cs309-psoc/lab_4_1/sw/hps/linux/rootfs/config_system.sh
Executable file
74
cs309-psoc/lab_4_1/sw/hps/linux/rootfs/config_system.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash -x
|
||||
# Configure the locale to have proper language support.
|
||||
localedef -i en_US -c -f UTF-8 en_US.UTF-8
|
||||
dpkg-reconfigure locales
|
||||
# Configure the timezone.
|
||||
echo "Europe/Zurich" > "/etc/timezone"
|
||||
dpkg-reconfigure -f noninteractive tzdata
|
||||
# Set the machine’s hostname.
|
||||
echo "DE0-Nano-SoC" > "/etc/hostname"
|
||||
tee "/etc/hosts" >"/dev/null" <<EOF
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 DE0-Nano-SoC
|
||||
EOF
|
||||
# Create the “/etc/network/interfaces” file that describes the network
|
||||
# interfaces available on the board.
|
||||
tee "/etc/network/interfaces" > "/dev/null" <<EOF
|
||||
# interfaces(5) file used by ifup(8) and ifdown(8)
|
||||
# The loopback network interface
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
# The primary network interface
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
EOF
|
||||
# DNS configuration for name resolution. We use google's public DNS server here.
|
||||
sudo tee "/etc/resolv.conf" > "/dev/null" <<EOF
|
||||
nameserver 8.8.8.8
|
||||
EOF
|
||||
# Configure Ubuntu Core to display a login shell on the serial console once the
|
||||
# kernel boots. We had previously configured U-Boot to supply the command-line
|
||||
# argument "console=ttyS0,115200" to the linux kernel. This argument instructs
|
||||
# the kernel to use serial console “ttyS0” as the boot shell, so here we choose
|
||||
# to use the same serial console for the login shell
|
||||
tee "/etc/init/ttyS0.conf" > "/dev/null" <<EOF
|
||||
# ttyS0 - getty
|
||||
#
|
||||
# This service maintains a getty on ttyS0
|
||||
description "Get a getty on ttyS0"
|
||||
start on runlevel [2345]
|
||||
stop on runlevel [016]
|
||||
respawn
|
||||
exec /sbin/getty -L 115200 ttyS0 vt102
|
||||
EOF
|
||||
# Create a user and a password. In this example, we create a user called
|
||||
# “sahand” with password "1234". Note that we compute an encrypted version of
|
||||
# the password, because useradd does not allow plain text passwords to be used
|
||||
# in non-interactive mode.
|
||||
username="sahand"
|
||||
password="1234"
|
||||
encrypted_password="$(perl -e 'printf("%s\n", crypt($ARGV[0], "password"))' "${password}")"
|
||||
useradd -m -p "${encrypted_password}" -s "/bin/bash" "${username}"
|
||||
# Ubuntu requires the admin to be part of the "adm" and "sudo" groups, so add
|
||||
# the previously-created user to the 2 groups.
|
||||
addgroup ${username} adm
|
||||
addgroup ${username} sudo
|
||||
# Set root password to "1234" (same as previously-created user).
|
||||
echo -e "${password}\n${password}\n" | passwd root
|
||||
# Remove "/rootfs_config.sh" from /etc/rc.local to avoid reconfiguring system on
|
||||
# next boot
|
||||
tee "/etc/rc.local" > "/dev/null" <<EOF
|
||||
#!/bin/sh -e
|
||||
#
|
||||
# rc.local
|
||||
#
|
||||
# This script is executed at the end of each multiuser runlevel.
|
||||
# Make sure that the script will "exit 0" on success or any other
|
||||
# value on error.
|
||||
#
|
||||
# In order to enable or disable this script just change the execution
|
||||
# bits.
|
||||
#
|
||||
# By default this script does nothing.
|
||||
exit 0
|
||||
EOF
|
Reference in New Issue
Block a user